[Rt-commit] rt branch, 4.2/template-name-instead-of-id, created. rt-4.0.4-251-ga119ea0

Ruslan Zakirov ruz at bestpractical.com
Fri Sep 14 17:07:23 EDT 2012


The branch, 4.2/template-name-instead-of-id has been created
        at  a119ea0004989b0bfac7c5989a6c22c0a4624230 (commit)

- Log -----------------------------------------------------------------
commit cc90fed2d3061875be1f4b3257bf28c898237989
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Apr 13 02:14:43 2012 +0400

    change Template column from id to Name

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 039a646..69aa24e 100755
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -141,7 +141,7 @@ CREATE TABLE Scrips (
 	CustomIsApplicableCode	CLOB,
 	CustomPrepareCode	CLOB,
 	CustomCommitCode	CLOB,
-	Template	NUMBER(11,0) DEFAULT 0 NOT NULL,
+	Template	VARCHAR2(200) NOT NULL,
   	Creator 	NUMBER(11,0) DEFAULT 0 NOT NULL,
   	Created 	DATE,
   	LastUpdatedBy 	NUMBER(11,0) DEFAULT 0 NOT NULL,
diff --git a/etc/schema.Pg b/etc/schema.Pg
index b4742fc..5af9167 100755
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -230,7 +230,7 @@ CREATE TABLE Scrips (
   CustomIsApplicableCode text NULL  ,
   CustomPrepareCode text NULL  ,
   CustomCommitCode text NULL  ,
-  Template integer NOT NULL DEFAULT 0  ,
+  Template varchar(200) NOT NULL,
   Creator integer NOT NULL DEFAULT 0  ,
   Created TIMESTAMP NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
diff --git a/etc/schema.SQLite b/etc/schema.SQLite
index 8867b03..4130ddb 100755
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@ -150,7 +150,7 @@ CREATE TABLE Scrips (
   CustomIsApplicableCode text NULL  ,
   CustomPrepareCode text NULL  ,
   CustomCommitCode text NULL  ,
-  Template integer NULL  ,
+  Template varchar(200) NOT NULL ,
   Creator integer NULL  ,
   Created DATETIME NULL  ,
   LastUpdatedBy integer NULL  ,
diff --git a/etc/schema.mysql b/etc/schema.mysql
index 44889a0..3646743 100755
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -142,7 +142,7 @@ CREATE TABLE Scrips (
   CustomIsApplicableCode text NULL  ,
   CustomPrepareCode text NULL  ,
   CustomCommitCode text NULL  ,
-  Template integer NOT NULL DEFAULT 0  ,
+  Template varchar(200) NOT NULL  ,
   Creator integer NOT NULL DEFAULT 0  ,
   Created DATETIME NULL  ,
   LastUpdatedBy integer NOT NULL DEFAULT 0  ,
diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index 8f130e2..bd0f673 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -1004,7 +1004,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =head2 Template
 
 Returns the current value of Template.
-(In the database, Template is stored as int(11).)
+(In the database, Template is stored as varchar(200).)
 
 
 
@@ -1013,7 +1013,7 @@ Returns the current value of Template.
 
 Set Template to VALUE.
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Template will be stored as a int(11).)
+(In the database, Template will be stored as a varchar(200).)
 
 
 =cut
@@ -1078,7 +1078,7 @@ sub _CoreAccessible {
         CustomCommitCode =>
 		{read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Template =>
-		{read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
+		{read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => 'Blank'},
         Creator =>
 		{read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created =>

commit 745253c7802a26019d637c3ffe6405a1ecda08da
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Apr 14 00:55:00 2012 +0400

    we don't need `require`s as we have `use`s

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index bd0f673..b1030a7 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -148,7 +148,6 @@ sub Create {
 
     #TODO +++ validate input
 
-    require RT::ScripAction;
     return ( 0, $self->loc("Action is mandatory argument") )
         unless $args{'ScripAction'};
     my $action = RT::ScripAction->new( $self->CurrentUser );
@@ -156,7 +155,6 @@ sub Create {
     return ( 0, $self->loc( "Action '[_1]' not found", $args{'ScripAction'} ) ) 
         unless $action->Id;
 
-    require RT::Template;
     return ( 0, $self->loc("Template is mandatory argument") )
         unless $args{'Template'};
     my $template = RT::Template->new( $self->CurrentUser );
@@ -164,7 +162,6 @@ sub Create {
     return ( 0, $self->loc( "Template '[_1]' not found", $args{'Template'} ) )
         unless $template->Id;
 
-    require RT::ScripCondition;
     return ( 0, $self->loc("Condition is mandatory argument") )
         unless $args{'ScripCondition'};
     my $condition = RT::ScripCondition->new( $self->CurrentUser );

commit 3eb2a4f4cf3cfd55932f7f26a971d3b1beb10ff1
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sat Apr 14 01:29:58 2012 +0400

    merge test files

diff --git a/t/api/template-insert.t b/t/api/template-insert.t
deleted file mode 100644
index 1bf5fc3..0000000
--- a/t/api/template-insert.t
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/perl
-
-use warnings;
-use strict;
-
-
-use RT;
-use RT::Test tests => 7;
-
-
-
-# This tiny little test script triggers an interaction bug between DBD::Oracle 1.16, SB 1.15 and RT 3.4
-
-use_ok('RT::Template');
-my $template = RT::Template->new(RT->SystemUser);
-
-isa_ok($template, 'RT::Template');
-my ($val,$msg) = $template->Create(Queue => 1,
-                  Name => 'InsertTest',
-                  Content => 'This is template content');
-ok($val,$msg);
-is($template->Name, 'InsertTest');
-is($template->Content, 'This is template content', "We created the object right");
-($val, $msg) = $template->SetContent( 'This is new template content');
-ok($val,$msg);
-is($template->Content, 'This is new template content', "We managed to _Set_ the content");
diff --git a/t/api/template.t b/t/api/template.t
index 2fadede..93f839a 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -1,25 +1,34 @@
 
 use strict;
 use warnings;
-use RT;
-use RT::Test tests => 2;
 
+use RT::Test tests => 8;
 
-{
-
-ok(require RT::Template);
 
+use_ok('RT::Template');
 
+{
+    my $template = RT::Template->new(RT->SystemUser);
+    isa_ok($template, 'RT::Template');
+    my ($val,$msg) = $template->Create(
+        Queue => 1,
+        Name => 'InsertTest',
+        Content => 'This is template content'
+    );
+    ok($val,$msg);
+
+    is( $template->Name, 'InsertTest');
+    is( $template->Content, 'This is template content', "We created the object right");
+
+    ($val, $msg) = $template->SetContent( 'This is new template content');
+    ok($val,$msg);
+    is($template->Content, 'This is new template content', "We managed to _Set_ the content");
 }
 
 {
-
-my $t = RT::Template->new(RT->SystemUser);
-$t->Create(Name => "Foo", Queue => 1);
-my $t2 = RT::Template->new(RT->Nobody);
-$t2->Load($t->Id);
-ok($t2->QueueObj->id, "Got the template's queue objet");
-
-
+    my $t = RT::Template->new(RT->SystemUser);
+    $t->Create(Name => "Foo", Queue => 1);
+    my $t2 = RT::Template->new(RT->Nobody);
+    $t2->Load($t->Id);
+    ok($t2->QueueObj->id, "Got the template's queue objet");
 }
-

commit 28da49a3c4497f093789caeedea0fc6bdf17362e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 15:50:36 2012 +0400

    make sure we can not create templates with duplicate names

diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index 6f0251d..bcd6874 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -232,6 +232,16 @@ sub Create {
         $args{'Queue'} = $QueueObj->Id;
     }
 
+    return ( undef, $self->loc('Name is required') )
+        unless $args{Name};
+
+    {
+        my $tmp = $self->new( RT->SystemUser );
+        $tmp->LoadByCols( Name => $args{'Name'}, Queue => $args{'Queue'} );
+        return ( undef, $self->loc('Template with that name already exist') )
+            if $tmp->id;
+    }
+
     my $result = $self->SUPER::Create(
         Content     => $args{'Content'},
         Queue       => $args{'Queue'},
diff --git a/t/api/template.t b/t/api/template.t
index 93f839a..62f8b3e 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -4,20 +4,26 @@ use warnings;
 
 use RT::Test tests => 8;
 
-
 use_ok('RT::Template');
 
+my $queue = RT::Test->load_or_create_queue( Name => 'Templates' );
+ok $queue && $queue->id, 'loaded or created queue';
+
 {
     my $template = RT::Template->new(RT->SystemUser);
     isa_ok($template, 'RT::Template');
+}
+
+{
+    my $template = RT::Template->new(RT->SystemUser);
     my ($val,$msg) = $template->Create(
-        Queue => 1,
-        Name => 'InsertTest',
+        Queue => $queue->id,
+        Name => 'Test',
         Content => 'This is template content'
     );
     ok($val,$msg);
 
-    is( $template->Name, 'InsertTest');
+    is( $template->Name, 'Test');
     is( $template->Content, 'This is template content', "We created the object right");
 
     ($val, $msg) = $template->SetContent( 'This is new template content');
@@ -25,6 +31,17 @@ use_ok('RT::Template');
     is($template->Content, 'This is new template content', "We managed to _Set_ the content");
 }
 
+note "can not create template with duplicate name";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok(!$val,$msg);
+}
+
 {
     my $t = RT::Template->new(RT->SystemUser);
     $t->Create(Name => "Foo", Queue => 1);
@@ -32,3 +49,17 @@ use_ok('RT::Template');
     $t2->Load($t->Id);
     ok($t2->QueueObj->id, "Got the template's queue objet");
 }
+
+sub clean_templates {
+    my %args = (@_);
+
+    my $templates = RT::Templates->new( RT->SystemUser );
+    $templates->Limit( FIELD => 'Queue', VALUE => $args{'Queue'} )
+        if defined $args{'Queue'};
+    $templates->Limit( FIELD => 'Name', VALUE => $_ )
+        foreach ref $args{'Name'}? @{$args{'Name'}} : ($args{'Name'}||());
+    while ( my $t = $templates->Next ) {
+        $t->Delete;
+    }
+}
+

commit cf7dbf143fad3da3da4e019609a4cf7a9bbb7c73
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 15:52:32 2012 +0400

    make sure we can not create template without name

diff --git a/t/api/template.t b/t/api/template.t
index 62f8b3e..f22af69 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -31,6 +31,14 @@ ok $queue && $queue->id, 'loaded or created queue';
     is($template->Content, 'This is new template content', "We managed to _Set_ the content");
 }
 
+note "can not create template w/o Name";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id );
+    ok(!$val,$msg);
+}
+
 note "can not create template with duplicate name";
 {
     clean_templates( Queue => $queue->id );

commit 8d3462f52c043f0081a1ef6f0450c801893c03e0
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 16:13:53 2012 +0400

    test that we can change template name

diff --git a/t/api/template.t b/t/api/template.t
index f22af69..e6e8626 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -50,6 +50,18 @@ note "can not create template with duplicate name";
     ok(!$val,$msg);
 }
 
+note "change template's name";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    ($val,$msg) = $template->SetName( 'Some' );
+    ($val,$msg);
+    is $template->Name, 'Some';
+}
+
 {
     my $t = RT::Template->new(RT->SystemUser);
     $t->Create(Name => "Foo", Queue => 1);

commit cb9506b43ceee8862223d878cbd0731b04cc2dee
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 16:18:18 2012 +0400

    make sure tmpl's name can't be set to empty or duplicate

diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index bcd6874..54c0959 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -607,6 +607,30 @@ sub CurrentUserHasQueueRight {
     return ( $self->QueueObj->CurrentUserHasRight(@_) );
 }
 
+=head2 SetName
+
+Change name of the template.
+
+=cut
+
+sub SetName {
+    my $self = shift;
+    my $value = shift;
+
+    return ( undef, $self->loc('Name is required') )
+        unless $value;
+
+    return $self->_Set( Field => 'Name', Value => $value )
+        if lc($self->Name) eq lc($value);
+
+    my $tmp = $self->new( RT->SystemUser );
+    $tmp->LoadByCols( Name => $value, Queue => $self->Queue );
+    return ( undef, $self->loc('Template with that name already exist') )
+        if $tmp->id;
+
+    return $self->_Set( Field => 'Name', Value => $value );
+}
+
 =head2 SetType
 
 If setting Type to Perl, require the ExecuteCode right.
diff --git a/t/api/template.t b/t/api/template.t
index e6e8626..b25e023 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -62,6 +62,30 @@ note "change template's name";
     is $template->Name, 'Some';
 }
 
+note "can not change name to empty";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    ($val,$msg) = $template->Create( Queue => $queue->id, Name => '' );
+    ok(!$val,$msg);
+    ($val,$msg) = $template->Create( Queue => $queue->id, Name => undef );
+    ok(!$val,$msg);
+}
+
+note "can not change name to duplicate";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Some' );
+    ok($val,$msg);
+}
+
 {
     my $t = RT::Template->new(RT->SystemUser);
     $t->Create(Name => "Foo", Queue => 1);

commit ce321cd6b873dbab2f92cfc6473c7abf33450d3d
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 16:40:37 2012 +0400

    make sure we can not change template's queue
    
    moving templates between queues gonna be too
    complicated

diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index 54c0959..44f4e4a 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -607,6 +607,17 @@ sub CurrentUserHasQueueRight {
     return ( $self->QueueObj->CurrentUserHasRight(@_) );
 }
 
+=head2 SetQueue
+
+Changing queue is not implemented.
+
+=cut
+
+sub SetQueue {
+    my $self = shift;
+    return ( undef, $self->loc('Changing queue is not implemented') );
+}
+
 =head2 SetName
 
 Change name of the template.
diff --git a/t/api/template.t b/t/api/template.t
index b25e023..ec86b57 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -9,6 +9,9 @@ use_ok('RT::Template');
 my $queue = RT::Test->load_or_create_queue( Name => 'Templates' );
 ok $queue && $queue->id, 'loaded or created queue';
 
+my $alt_queue = RT::Test->load_or_create_queue( Name => 'Alternative' );
+ok $alt_queue && $alt_queue->id, 'loaded or created queue';
+
 {
     my $template = RT::Template->new(RT->SystemUser);
     isa_ok($template, 'RT::Template');
@@ -86,6 +89,17 @@ note "can not change name to duplicate";
     ok($val,$msg);
 }
 
+note "changing queue of template is not implemented";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    ($val,$msg) = $template->SetQueue( $alt_queue->id );
+    ok(!$val,$msg);
+}
+
 {
     my $t = RT::Template->new(RT->SystemUser);
     $t->Create(Name => "Foo", Queue => 1);

commit 819a6d9636261e0a3d0e90c76160b73c029e0391
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 16:53:15 2012 +0400

    test that we can not delete template with scrips

diff --git a/t/api/template.t b/t/api/template.t
index ec86b57..3ed9a99 100644
--- a/t/api/template.t
+++ b/t/api/template.t
@@ -100,6 +100,27 @@ note "changing queue of template is not implemented";
     ok(!$val,$msg);
 }
 
+note "make sure template can not be deleted if it has scrips";
+{
+    clean_templates( Queue => $queue->id );
+    my $template = RT::Template->new( RT->SystemUser );
+    my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' );
+    ok($val,$msg);
+
+    my $scrip = RT::Scrip->new( RT->SystemUser );
+    ($val,$msg) = $scrip->Create(
+        Queue => $queue->id,
+        ScripCondition => "On Create",
+        ScripAction => 'Autoreply To Requestors',
+        Template => $template->Name,
+    );
+    ok($val, $msg);
+
+    ($val, $msg) = $template->Delete;
+    ok(!$val,$msg);
+}
+
+
 {
     my $t = RT::Template->new(RT->SystemUser);
     $t->Create(Name => "Foo", Queue => 1);

commit 8a19051c7146a6d9636faa1dcbb34f91d0b4d7a7
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Apr 16 17:37:19 2012 +0400

    save Name in Template column of scrips

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index b1030a7..556f6ad 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -170,7 +170,7 @@ sub Create {
         unless $condition->Id;
 
     my ( $id, $msg ) = $self->SUPER::Create(
-        Template               => $template->Id,
+        Template               => $template->Name,
         ScripCondition         => $condition->id,
         ScripAction            => $action->Id,
         Description            => $args{'Description'},
@@ -807,7 +807,7 @@ sub SetTemplate {
     return ( 0, $self->loc( "Template '[_1]' not found", $value ) )
       unless $template->Id;
 
-    return $self->_Set( Field => 'Template', Value => $template->Id );
+    return $self->_Set( Field => 'Template', Value => $template->Name );
 }
 
 1;
diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index c679a91..df3a4e4 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -197,7 +197,7 @@ sub TemplateObj {
     return undef unless $self->{Template};
     if ( !$self->{'TemplateObj'} ) {
         $self->{'TemplateObj'} = RT::Template->new( $self->CurrentUser );
-        $self->{'TemplateObj'}->LoadById( $self->{'Template'} );
+        $self->{'TemplateObj'}->Load( $self->{'Template'} );
 
         if ( ( $self->{'TemplateObj'}->__Value('Queue') == 0 )
             && $self->{'_TicketObj'} ) {

commit b050078675a386ce5befdf76cb358a75a2f02200
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Sep 12 20:26:52 2012 +0400

    use $scrip->Template rather than ->TemplateObj->Name
    
    Template column in scrips now holds Name.
    
    Since we apply scrips to multiple queues TemplateObj
    becomes ambiguous, the same scrip may use different
    template object depending on queue. The name stays
    the same.
    
    Old variant should still work, but I think it's better
    to avoid using TemplateObj without context.

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index 556f6ad..e48351d 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -265,7 +265,7 @@ sub AddToObject {
         )
     ;
 
-    my $tname = $self->TemplateObj->Name;
+    my $tname = $self->Template;
     my $template = RT::Template->new( $self->CurrentUser );
     $template->LoadQueueTemplate( Queue => $queue? $queue->id : 0, Name => $tname );
     $template->LoadGlobalTemplate( $tname ) if $queue && !$template->id;
diff --git a/lib/RT/Shredder/Plugin/Summary.pm b/lib/RT/Shredder/Plugin/Summary.pm
index 95f6d8f..53f4473 100644
--- a/lib/RT/Shredder/Plugin/Summary.pm
+++ b/lib/RT/Shredder/Plugin/Summary.pm
@@ -142,7 +142,7 @@ sub WriteDownScrip {
     my $props = $self->_MakeHash( $args{'Object'} );
     $props->{'Action'} = $args{'Object'}->ActionObj->Name;
     $props->{'Condition'} = $args{'Object'}->ConditionObj->Name;
-    $props->{'Template'} = $args{'Object'}->TemplateObj->Name;
+    $props->{'Template'} = $args{'Object'}->Template;
     $props->{'Queue'} = $args{'Object'}->QueueObj->Name || 'global';
 
     return $self->_WriteDownHash( $args{'Object'}, $props );
diff --git a/share/html/Admin/Scrips/Elements/SelectTemplate b/share/html/Admin/Scrips/Elements/SelectTemplate
index 99fe82a..f61ce2a 100755
--- a/share/html/Admin/Scrips/Elements/SelectTemplate
+++ b/share/html/Admin/Scrips/Elements/SelectTemplate
@@ -63,7 +63,7 @@ $Default => undef
 <%INIT>
 
 my $current;
-$current = $Scrip->TemplateObj->Name if $Scrip;
+$current = $Scrip->Template if $Scrip;
 
 my $global = RT::Templates->new($session{'CurrentUser'});
 $global->LimitToGlobal;
diff --git a/share/html/Elements/RT__Scrip/ColumnMap b/share/html/Elements/RT__Scrip/ColumnMap
index 0f5a476..3a06074 100644
--- a/share/html/Elements/RT__Scrip/ColumnMap
+++ b/share/html/Elements/RT__Scrip/ColumnMap
@@ -78,14 +78,14 @@ my $COLUMN_MAP = {
     },
     Template => {
         title     => 'Template', # loc
-        value     => sub { return $_[0]->loc( $_[0]->TemplateObj->Name ) },
+        value     => sub { return $_[0]->loc( $_[0]->Template ) },
     },
     AutoDescription => {
         title     => 'Condition, Action and Template', # loc
         value     => sub { return $_[0]->loc( "[_1] [_2] with template [_3]",
             $_[0]->loc($_[0]->ConditionObj->Name),
             $_[0]->loc($_[0]->ActionObj->Name),
-            $_[0]->loc($_[0]->TemplateObj->Name),
+            $_[0]->loc($_[0]->Template),
         ) },
     },
     Description => {
diff --git a/share/html/Ticket/Elements/PreviewScrips b/share/html/Ticket/Elements/PreviewScrips
index 8a3364e..d8dc541 100755
--- a/share/html/Ticket/Elements/PreviewScrips
+++ b/share/html/Ticket/Elements/PreviewScrips
@@ -67,7 +67,7 @@ return unless $Object;
 %                  @{$Object->Scrips->Prepared};
 %     for my $scrip (@scrips) {
           <b><% $scrip->Description || loc('Scrip #[_1]',$scrip->id) %></b><br />
-          <&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)&>[_1] [_2] with template [_3]</&>
+          <&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->Template)&>[_1] [_2] with template [_3]</&>
           <br />
 %         for my $type (qw(To Cc Bcc)) {
 %             my @addresses =  $scrip->ActionObj->Action->$type();

commit 78f78491eafe637accdcf40069e262436c31e11e
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:10:48 2012 +0400

    RT::Template->LoadByName method
    
    Loads queue's or global template

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index e48351d..0e192eb 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -267,8 +267,7 @@ sub AddToObject {
 
     my $tname = $self->Template;
     my $template = RT::Template->new( $self->CurrentUser );
-    $template->LoadQueueTemplate( Queue => $queue? $queue->id : 0, Name => $tname );
-    $template->LoadGlobalTemplate( $tname ) if $queue && !$template->id;
+    $template->LoadByName( Queue => $queue? $queue->id : 0, Name => $tname );
     unless ( $template->id ) {
         if ( $queue ) {
             return (0, $self->loc('No template [_1] in the queue', $tname));
diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index 44f4e4a..d1b2faf 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -127,7 +127,7 @@ Load a template, either by number or by name.
 Note that loading templates by name using this method B<is
 ambiguous>. Several queues may have template with the same name
 and as well global template with the same name may exist.
-Use L</LoadGlobalTemplate> and/or L<LoadQueueTemplate> to get
+Use L</LoadByName>, L</LoadGlobalTemplate> or L<LoadQueueTemplate> to get
 precise result.
 
 =cut
@@ -143,6 +143,37 @@ sub Load {
     return $self->LoadById( $identifier );
 }
 
+=head2 LoadByName
+
+Takes Name and Queue arguments. Tries to load queue specific template
+first, then global. If Queue argument is omitted then global template
+is tried, not template with the name in any queue.
+
+=cut
+
+sub LoadByName {
+    my $self = shift;
+    my %args = (
+        Queue => undef,
+        Name  => undef,
+        @_
+    );
+    my $queue = $args{'Queue'};
+    if ( blessed $queue ) {
+        $queue = $queue->id;
+    } elsif ( $queue =~ /\D/ ) {
+        my $tmp = RT::Queue->new( $self->CurrentUser );
+        $tmp->Load($queue);
+        $queue = $tmp->id;
+    }
+
+    return $self->LoadGlobalTemplate( $args{'Name'} ) unless $queue;
+
+    $self->LoadQueueTemplate( Queue => $queue, Name => $args{'Name'} );
+    return $self->id if $self->id;
+    return $self->LoadGlobalTemplate( $args{'Name'} );
+}
+
 =head2 LoadGlobalTemplate NAME
 
 Load the global template with the name NAME
@@ -161,18 +192,7 @@ sub LoadGlobalTemplate {
 Loads the Queue template named NAME for Queue QUEUE.
 
 Note that this method doesn't load a global template with the same name
-if template in the queue doesn't exist. THe following code can be used:
-
-    $template->LoadQueueTemplate( Queue => $queue_id, Name => $template_name );
-    unless ( $template->id ) {
-        $template->LoadGlobalTemplate( $template_name );
-        unless ( $template->id ) {
-            # no template
-            ...
-        }
-    }
-    # ok, template either queue's or global
-    ...
+if template in the queue doesn't exist. Use L</LoadByName>.
 
 =cut
 

commit eca9f2ced23428b24aeae8800398c34807404144
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:11:31 2012 +0400

    more details in an error message

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index 0e192eb..be510da 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -270,7 +270,8 @@ sub AddToObject {
     $template->LoadByName( Queue => $queue? $queue->id : 0, Name => $tname );
     unless ( $template->id ) {
         if ( $queue ) {
-            return (0, $self->loc('No template [_1] in the queue', $tname));
+            return (0, $self->loc('No template [_1] in queue [_2] or global',
+                    $tname, $queue->Name||$queue->id));
         } else {
             return (0, $self->loc('No global template [_1]', $tname));
         }

commit a3e3ec5adc4f07fc917d6b099623c49a0b0ab352
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:12:19 2012 +0400

    undef as default Template arg in Scrip->Create, not 0

diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index be510da..efedd15 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -107,7 +107,7 @@ sub Create {
     my $self = shift;
     my %args = (
         Queue                  => 0,
-        Template               => 0,                     # name or id
+        Template               => undef,                 # name or id
         ScripAction            => 0,                     # name or id
         ScripCondition         => 0,                     # name or id
         Stage                  => 'TransactionCreate',

commit d7f7b9a76566494fa24cc4b13600f4da55445f92
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Nov 29 19:44:12 2011 +0400

    IsEmpty column map for templates

diff --git a/share/html/Elements/RT__Template/ColumnMap b/share/html/Elements/RT__Template/ColumnMap
index d9d55cf..b983d31 100644
--- a/share/html/Elements/RT__Template/ColumnMap
+++ b/share/html/Elements/RT__Template/ColumnMap
@@ -78,6 +78,10 @@ my $COLUMN_MAP = {
         title     => 'Queue', # loc
         value     => sub { $_[0]->Queue },
     },
+    IsEmpty => {
+        title     => 'Empty', # loc
+        value     => sub { $_[0]->IsEmpty? $_[0]->loc('Yes') : $_[0]->loc('No') },
+    },
 };
 
 </%ONCE>

commit 9f8aedcf0f61372e5024dddc8e6c8c103500b150
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Nov 29 19:47:40 2011 +0400

    $tmpl->UsedBy, $scrips->LimitByTemplate methods and UsedBy ColumnMap
    
    $scrips->LimitByTemplate - limits to scrips that
    really use particular template, accounts that global
    templates can be overriden.
    
    $tmpl->UsedBy - sugar for above from template side.
    
    UsedBy column map for templates that shows links to
    scrips.

diff --git a/lib/RT/Scrips.pm b/lib/RT/Scrips.pm
index deb22c4..95936d1 100644
--- a/lib/RT/Scrips.pm
+++ b/lib/RT/Scrips.pm
@@ -159,6 +159,85 @@ sub LimitToEnabled {
     );
 }
 
+=head2 LimitByTemplate
+
+Takes a L<RT::Template> object and limits scrips to those that
+use the template.
+
+=cut
+
+sub LimitByTemplate {
+    my $self = shift;
+    my $template = shift;
+
+    $self->Limit( FIELD => 'Template', VALUE => $template->Name );
+
+    if ( $template->Queue ) {
+        # if template is local then we are interested in global and
+        # queue specific scrips
+        $self->LimitToQueue( $template->Queue );
+        $self->LimitToGlobal;
+    }
+    else { # template is global
+
+        # if every queue has a custom version then there
+        # is no scrip that uses the template
+        {
+            my $queues = RT::Queues->new( RT->SystemUser );
+            my $alias = $queues->Join(
+                TYPE   => 'LEFT',
+                ALIAS1 => 'main',
+                FIELD1 => 'id',
+                TABLE2 => 'Templates',
+                FIELD2 => 'Queue',
+            );
+            $queues->Limit(
+                LEFTJOIN   => $alias,
+                ALIAS      => $alias,
+                FIELD      => 'Name',
+                VALUE      => $template->Name,
+            );
+            $queues->Limit(
+                ALIAS      => $alias,
+                FIELD      => 'id',
+                OPERATOR   => 'IS',
+                VALUE      => 'NULL',
+            );
+            return $self->Limit( FIELD => 'id', VALUE => 0 )
+                unless $queues->Count;
+        }
+
+        # otherwise it's either a global scrip or application to
+        # a queue with custom version of the template.
+        my $os_alias = RT::ObjectScrips->new( $self->CurrentUser )
+            ->JoinTargetToThis( $self );
+        my $tmpl_alias = $self->Join(
+            TYPE   => 'LEFT',
+            ALIAS1 => $os_alias,
+            FIELD1 => 'ObjectId',
+            TABLE2 => 'Templates',
+            FIELD2 => 'Queue',
+        );
+        $self->Limit(
+            LEFTJOIN => $tmpl_alias, ALIAS => $tmpl_alias, FIELD => 'Name', VALUE => $template->Name,
+        );
+        $self->Limit(
+            LEFTJOIN => $tmpl_alias, ALIAS => $tmpl_alias, FIELD => 'Queue', OPERATOR => '!=', VALUE => 0,
+        );
+
+        $self->_OpenParen('UsedBy');
+        $self->Limit( SUBCLAUSE => 'UsedBy', ALIAS => $os_alias, FIELD => 'ObjectId', VALUE => 0 );
+        $self->Limit(
+            SUBCLAUSE => 'UsedBy',
+            ALIAS => $tmpl_alias,
+            FIELD => 'id',
+            OPERATOR => 'IS',
+            VALUE => 'NULL',
+        );
+        $self->_CloseParen('UsedBy');
+    }
+}
+
 sub ApplySortOrder {
     my $self = shift;
     my $order = shift || 'ASC';
diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index d1b2faf..e18e6d7 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -290,6 +290,21 @@ sub Delete {
     return ( $self->SUPER::Delete(@_) );
 }
 
+=head2 UsedBy
+
+Returns L<RT::Scrips> limitted to scrips that use this template. Takes
+into account that template can be overriden in a queue.
+
+=cut
+
+sub UsedBy {
+    my $self = shift;
+
+    my $scrips = RT::Scrips->new( $self->CurrentUser );
+    $scrips->LimitByTemplate( $self );
+    return $scrips;
+}
+
 =head2 IsEmpty
 
 Returns true value if content of the template is empty, otherwise
diff --git a/share/html/Elements/RT__Template/ColumnMap b/share/html/Elements/RT__Template/ColumnMap
index b983d31..6c821a6 100644
--- a/share/html/Elements/RT__Template/ColumnMap
+++ b/share/html/Elements/RT__Template/ColumnMap
@@ -82,6 +82,20 @@ my $COLUMN_MAP = {
         title     => 'Empty', # loc
         value     => sub { $_[0]->IsEmpty? $_[0]->loc('Yes') : $_[0]->loc('No') },
     },
+    UsedBy => {
+        title     => 'Used by scrips', # loc
+        value     => sub {
+            my @res;
+            my $scrips = $_[0]->UsedBy;
+            while ( my $scrip = $scrips->Next ) {
+                push @res, ', ' if @res;
+                push @res, \'<a href="', RT->Config->Get('WebPath'), '/Admin/Scrips/Modify.html';
+                push @res, '?id='. $scrip->id;
+                push @res, \'" title="', $scrip->Description, \'">', $scrip->id, \'</a>';
+            }
+            return @res;
+        },
+    },
 };
 
 </%ONCE>

commit 2baa4e23694cda6acdbe59171eda2ac648e06f38
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Nov 29 19:48:09 2011 +0400

    show UsedBy and IsEmpty columns in templates AdminUI

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index d8e8780..382f6d0 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -2473,7 +2473,7 @@ Set(%AdminSearchResultFormat,
     Templates =>
         q{'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__id__</a>/TITLE:#'}
         .q{,'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__Name__</a>/TITLE:Name'}
-        .q{,'__Description__'},
+        .q{,'__Description__','__UsedBy__','__IsEmpty__'},
     Classes =>
         q{ '<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__id__</a>/TITLE:#'}
         .q{,'<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}

commit 5e78f4eeecec55f15d80da0f620384c19e171fbe
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:41:21 2012 +0400

    tidy, no code change, tiny doc changes
    
    retab, indent, drop useless space only and empty lines,
    drop some comments, several very small doc changes

diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index df3a4e4..84afd37 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -48,21 +48,13 @@
 
 =head1 NAME
 
-  RT::ScripAction - RT Action object
-
-=head1 SYNOPSIS
-
-  use RT::ScripAction;
-
+RT::ScripAction - RT Action object
 
 =head1 DESCRIPTION
 
-This module should never be called directly by client code. it's an internal module which
-should only be accessed through exported APIs in other modules.
-
-
-
-=head1 METHODS
+This module should never be called directly by client code. it's an
+internal module which should only be accessed through exported APIs
+in other modules.
 
 =cut
 
@@ -76,29 +68,29 @@ use base 'RT::Record';
 
 sub Table {'ScripActions'}
 
-
-
 use RT::Template;
 
 sub _Accessible  {
     my $self = shift;
-    my %Cols = ( Name  => 'read',
-		 Description => 'read',
-		 ExecModule  => 'read',
-		 Argument  => 'read',
-		 Creator => 'read/auto',
-		 Created => 'read/auto',
-		 LastUpdatedBy => 'read/auto',
-		 LastUpdated => 'read/auto'
-       );
+    my %Cols = (
+        Name  => 'read',
+        Description => 'read',
+        ExecModule  => 'read',
+        Argument  => 'read',
+        Creator => 'read/auto',
+        Created => 'read/auto',
+        LastUpdatedBy => 'read/auto',
+        LastUpdated => 'read/auto'
+    );
     return($self->SUPER::_Accessible(@_, %Cols));
 }
 
 
+=head1 METHODS
+
 =head2 Create
 
-Takes a hash. Creates a new Action entry.  should be better
-documented.
+Takes a hash. Creates a new Action entry.
 
 =cut
 
@@ -110,7 +102,6 @@ sub Create  {
 
 sub Delete  {
     my $self = shift;
-    
     return (0, "ScripAction->Delete not implemented");
 }
 
@@ -126,25 +117,23 @@ Returns: Id, Error Message
 sub Load  {
     my $self = shift;
     my $identifier = shift;
-    
+
     if (!$identifier) {
-	return (0, $self->loc('Input error'));
-    }	    
-    
+        return (0, $self->loc('Input error'));
+    }
+
     my ($ok, $msg);
     if ($identifier !~ /\D/) {
-	($ok, $msg) = $self->SUPER::Load($identifier);
+        ($ok, $msg) = $self->SUPER::Load($identifier);
     }
     else {
-	($ok, $msg) = $self->LoadByCol('Name', $identifier);
-	
+        ($ok, $msg) = $self->LoadByCol('Name', $identifier);
     }
 
     if (@_) {
-	# Set the template Id to the passed in template    
-	my $template = shift;
-	
-	$self->{'Template'} = $template;
+        # Set the template Id to the passed in template
+        my $template = shift;
+        $self->{'Template'} = $template;
     }
 
     return ($ok, $msg);
@@ -153,33 +142,36 @@ sub Load  {
 
 =head2 LoadAction HASH
 
-  Takes a hash consisting of TicketObj and TransactionObj.  Loads an RT::Action:: module.
+Takes a hash consisting of TicketObj and TransactionObj.  Loads an RT::Action:: module.
 
 =cut
 
 sub LoadAction  {
     my $self = shift;
-    my %args = ( TransactionObj => undef,
-		 TicketObj => undef,
-		 @_ );
+    my %args = (
+        TransactionObj => undef,
+        TicketObj => undef,
+        ScripObj => undef,
+        @_
+    );
 
     $self->{_TicketObj} = $args{TicketObj};
-    
-    #TODO: Put this in an eval  
+
     $self->ExecModule =~ /^(\w+)$/;
     my $module = $1;
     my $type = "RT::Action::". $module;
- 
+
     eval "require $type" || die "Require of $type failed.\n$@\n";
-    
-    $self->{'Action'}  = $type->new ( Argument => $self->Argument,
-                                      CurrentUser => $self->CurrentUser,
-                                      ScripActionObj => $self, 
-                                      ScripObj => $args{'ScripObj'},
-                                      TemplateObj => $self->TemplateObj,
-                                      TicketObj => $args{'TicketObj'},
-                                      TransactionObj => $args{'TransactionObj'},
-				    );
+
+    return $self->{'Action'} = $type->new(
+        Argument => $self->Argument,
+        CurrentUser => $self->CurrentUser,
+        ScripActionObj => $self,
+        ScripObj => $args{'ScripObj'},
+        TemplateObj => $self->TemplateObj,
+        TicketObj => $args{'TicketObj'},
+        TransactionObj => $args{'TransactionObj'},
+    );
 }
 
 
@@ -187,9 +179,6 @@ sub LoadAction  {
 
 Return this action's template object
 
-TODO: Why are we not using the Scrip's template object?
-
-
 =cut
 
 sub TemplateObj {
@@ -217,27 +206,20 @@ sub TemplateObj {
     return ( $self->{'TemplateObj'} );
 }
 
-# The following methods call the action object
-
-
 sub Prepare  {
     my $self = shift;
     $self->{_Message_ID} = 0;
-    return ($self->Action->Prepare());
-  
+    return $self->Action->Prepare();
 }
 
 sub Commit  {
     my $self = shift;
-    return($self->Action->Commit());
-    
-    
+    return $self->Action->Commit();
 }
 
 sub Describe  {
     my $self = shift;
-    return ($self->Action->Describe());
-    
+    return $self->Action->Describe();
 }
 
 =head2 Action
@@ -248,7 +230,7 @@ Return the actual RT::Action object for this scrip.
 
 sub Action {
     my $self = shift;
-    return ($self->{'Action'});
+    return $self->{'Action'};
 }
 
 sub DESTROY {
@@ -258,15 +240,6 @@ sub DESTROY {
     $self->{'TemplateObj'} = undef;
 }
 
-=head2 TODO
-
-Between this, RT::Scrip and RT::Action::*, we need to be able to get rid of a 
-class. This just reeks of too much complexity -- jesse
-
-=cut
-
-
-
 
 =head2 id
 
@@ -274,139 +247,98 @@ Returns the current value of id.
 (In the database, id is stored as int(11).)
 
 
-=cut
-
-
 =head2 Name
 
 Returns the current value of Name.
 (In the database, Name is stored as varchar(200).)
 
-
-
 =head2 SetName VALUE
 
-
 Set Name to VALUE.
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 (In the database, Name will be stored as a varchar(200).)
 
 
-=cut
-
-
 =head2 Description
 
 Returns the current value of Description.
 (In the database, Description is stored as varchar(255).)
 
-
-
 =head2 SetDescription VALUE
 
-
 Set Description to VALUE.
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 (In the database, Description will be stored as a varchar(255).)
 
 
-=cut
-
-
 =head2 ExecModule
 
 Returns the current value of ExecModule.
 (In the database, ExecModule is stored as varchar(60).)
 
-
-
 =head2 SetExecModule VALUE
 
-
 Set ExecModule to VALUE.
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 (In the database, ExecModule will be stored as a varchar(60).)
 
 
-=cut
-
-
 =head2 Argument
 
 Returns the current value of Argument.
 (In the database, Argument is stored as varbinary(255).)
 
-
-
 =head2 SetArgument VALUE
 
-
 Set Argument to VALUE.
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 (In the database, Argument will be stored as a varbinary(255).)
 
 
-=cut
-
-
 =head2 Creator
 
 Returns the current value of Creator.
 (In the database, Creator is stored as int(11).)
 
-
-=cut
-
-
 =head2 Created
 
 Returns the current value of Created.
 (In the database, Created is stored as datetime.)
 
-
-=cut
-
-
 =head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy.
 (In the database, LastUpdatedBy is stored as int(11).)
 
-
-=cut
-
-
 =head2 LastUpdated
 
 Returns the current value of LastUpdated.
 (In the database, LastUpdated is stored as datetime.)
 
-
 =cut
 
 
-
 sub _CoreAccessible {
     {
 
         id =>
-		{read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 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, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  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, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  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, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  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, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varbinary(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varbinary(255)', default => ''},
         Creator =>
-		{read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 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, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  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, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 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, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
+                {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };

commit ef4da1d8d6209f00be12737ec99b558e27162f00
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:49:51 2012 +0400

    pass arguments further to Action

diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index 84afd37..2123da6 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -209,17 +209,17 @@ sub TemplateObj {
 sub Prepare  {
     my $self = shift;
     $self->{_Message_ID} = 0;
-    return $self->Action->Prepare();
+    return $self->Action->Prepare( @_ );
 }
 
 sub Commit  {
     my $self = shift;
-    return $self->Action->Commit();
+    return $self->Action->Commit( @_ );
 }
 
 sub Describe  {
     my $self = shift;
-    return $self->Action->Describe();
+    return $self->Action->Describe( @_ );
 }
 
 =head2 Action

commit 81b900cd3a3de1842781b5e5761667f5e54e32f3
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 13:51:57 2012 +0400

    these DESTROY methods are useless
    
    It looks like an atempt to fix memory leak, but really
    it's impossible to fix circular references by sticking
    in custom DESTROY functions around. No object is
    destroyed in a cycle.

diff --git a/lib/RT/Action.pm b/lib/RT/Action.pm
index f05c191..2aa7439 100644
--- a/lib/RT/Action.pm
+++ b/lib/RT/Action.pm
@@ -179,19 +179,6 @@ sub IsApplicable  {
   return(undef);
 }
 
-sub DESTROY {
-    my $self = shift;
-
-    # We need to clean up all the references that might maybe get
-    # oddly circular
-    $self->{'ScripActionObj'} = undef;
-    $self->{'ScripObj'} = undef;
-    $self->{'TemplateObj'} =undef
-    $self->{'TicketObj'} = undef;
-    $self->{'TransactionObj'} = undef;
-}
-
-
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index 2123da6..ad6ece2 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -233,14 +233,6 @@ sub Action {
     return $self->{'Action'};
 }
 
-sub DESTROY {
-    my $self=shift;
-    $self->{'_TicketObj'} = undef;
-    $self->{'Action'} = undef;
-    $self->{'TemplateObj'} = undef;
-}
-
-
 =head2 id
 
 Returns the current value of id.
diff --git a/lib/RT/ScripCondition.pm b/lib/RT/ScripCondition.pm
index 3f24f2e..cafc6e2 100644
--- a/lib/RT/ScripCondition.pm
+++ b/lib/RT/ScripCondition.pm
@@ -209,16 +209,6 @@ sub IsApplicable  {
 }
 
 
-sub DESTROY {
-    my $self=shift;
-    $self->{'Condition'} = undef;
-}
-
-
-
-
-
-
 
 =head2 id
 

commit f80a1ff3c1f05f158ac4dedb5f4f3267c0e575b9
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 17:01:17 2012 +0400

    drop RT::Action->IsApplicable
    
    This was never documented, never used, no code calls it.

diff --git a/lib/RT/Action.pm b/lib/RT/Action.pm
index 2aa7439..afe993a 100644
--- a/lib/RT/Action.pm
+++ b/lib/RT/Action.pm
@@ -172,13 +172,6 @@ sub Prepare  {
 }
 
 
-#If this rule applies to this transaction, return true.
-
-sub IsApplicable  {
-  my $self = shift;
-  return(undef);
-}
-
 RT::Base->_ImportOverlays();
 
 1;

commit cab6f9f3c9a0e84ba50fa581b3fedc3268ece8ec
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Sep 13 17:11:57 2012 +0400

    we don't need to set $self->{'table'}
    
    Since we use Table class methods that return constant table names,
    we don't need to set $self->{'table'}

diff --git a/lib/RT/ScripCondition.pm b/lib/RT/ScripCondition.pm
index cafc6e2..92b726f 100644
--- a/lib/RT/ScripCondition.pm
+++ b/lib/RT/ScripCondition.pm
@@ -78,13 +78,6 @@ use base 'RT::Record';
 sub Table {'ScripConditions'}
 
 
-
-sub _Init  {
-    my $self = shift; 
-    $self->{'table'} = "ScripConditions";
-    return ($self->SUPER::_Init(@_));
-}
-
 sub _Accessible  {
     my $self = shift;
     my %Cols = ( Name  => 'read',

commit fcd537ee5194f654c8446888ad93cc181f48bdc9
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Sep 14 21:39:19 2012 +0400

    upgrade step for Template column in Scrips table
    
    Convert type of the column in schema.* files and
    in content file turn number into Name.

diff --git a/etc/upgrade/4.1.3/content b/etc/upgrade/4.1.3/content
new file mode 100644
index 0000000..8e907ee
--- /dev/null
+++ b/etc/upgrade/4.1.3/content
@@ -0,0 +1,33 @@
+use strict; use warnings;
+
+our @Initial = (
+    # upgrade Template from id to name
+    sub {
+        require RT::Scrips;
+        my $scrips = RT::Scrips->new( RT->SystemUser );
+        $scrips->UnLimit;
+        while ( my $scrip = $scrips->Next ) {
+            my $id = $scrip->Template;
+            if ( $id =~ /\D/ ) {
+                $RT::Logger->info('Template column for scrip #'. $scrip->id .' already contains characters');
+                next;
+            }
+
+            my $name;
+
+            my $template = RT::Template->new( RT->SystemUser );
+            $template->Load( $id );
+            unless ( $template->id ) {
+                $RT::Logger->error("Scrip #". $scrip->id ." has template set to #$id, but it's not in DB, setting it 'Blank'");
+                $name = 'Blank';
+            } else {
+                $name = $template->Name;
+            }
+
+            my ($status, $msg) = $scrip->_Set( Field => 'Template', Value => $name );
+            unless ( $status ) {
+                $RT::Logger->error("Couldn't set template: $msg");
+            }
+        }
+    },
+);
diff --git a/etc/upgrade/4.1.3/schema.Oracle b/etc/upgrade/4.1.3/schema.Oracle
new file mode 100644
index 0000000..b0b4d4c
--- /dev/null
+++ b/etc/upgrade/4.1.3/schema.Oracle
@@ -0,0 +1,5 @@
+# Template column
+ALTER TABLE Scrips RENAME COLUMN Template TO TemplateOld;
+ALTER TABLE Scrips ADD COLUMN Template VARCHAR2(200) NOT NULL;
+UPDATE TABLE Scrips SET Template = CAST(TemplateOld AS varchar2);
+ALTER TABLE Scrips DROP COLUMN TemplateOld;
\ No newline at end of file
diff --git a/etc/upgrade/4.1.3/schema.Pg b/etc/upgrade/4.1.3/schema.Pg
new file mode 100644
index 0000000..3a12d4d
--- /dev/null
+++ b/etc/upgrade/4.1.3/schema.Pg
@@ -0,0 +1,2 @@
+# Template colum
+ALTER TABLE Scrips ALTER COLUMN Template TYPE varchar(200);
diff --git a/etc/upgrade/4.1.3/schema.mysql b/etc/upgrade/4.1.3/schema.mysql
new file mode 100644
index 0000000..d35d730
--- /dev/null
+++ b/etc/upgrade/4.1.3/schema.mysql
@@ -0,0 +1,2 @@
+# Template column
+ALTER TABLE Scrips CHANGE Template Template varchar(200) NOT NULL;

commit a119ea0004989b0bfac7c5989a6c22c0a4624230
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Sep 14 23:27:03 2012 +0400

    change how we pass template to RT::Action::*
    
    New way is just passing correct Template object to LoadAction
    module along with other things RT::Actions have access to.
    
    Old way was to pass template name/id as second argument to
    ScripAction->Load (deprecated), then call ScripAction->TemplateObj
    method (deprecated) and call it only from LoadAction as it's only
    place where we have Ticket to get proper queue specific template.
    
    Old code is still there, but it gives warnings.

diff --git a/lib/RT/Rule.pm b/lib/RT/Rule.pm
index e2cd8e0..3642319 100644
--- a/lib/RT/Rule.pm
+++ b/lib/RT/Rule.pm
@@ -103,11 +103,10 @@ sub RunScripAction {
 
     my $action = $ScripAction->LoadAction( TransactionObj => $self->TransactionObj,
                                            TicketObj => $self->TicketObj,
+                                           TemplateObj => $template,
                                            %args,
                                        );
 
-    # XXX: fix template to allow additional arguments to be passed from here
-    $action->{'TemplateObj'} = $template;
     $action->{'ScripObj'} = RT::Scrip->new($self->CurrentUser); # Stub. sendemail action really wants a scripobj available
     $action->Prepare or return;
     $action->Commit;
diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index efedd15..0bf2216 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -315,12 +315,8 @@ sub ActionObj {
 
     unless ( defined $self->{'ScripActionObj'} ) {
         require RT::ScripAction;
-
         $self->{'ScripActionObj'} = RT::ScripAction->new( $self->CurrentUser );
-
-        #TODO: why are we loading Actions with templates like this.
-        # two separate methods might make more sense
-        $self->{'ScripActionObj'}->Load( $self->ScripAction, $self->Template );
+        $self->{'ScripActionObj'}->Load( $self->ScripAction );
     }
     return ( $self->{'ScripActionObj'} );
 }
@@ -364,13 +360,11 @@ Retuns an RT::Template object with this Scrip\'s Template
 
 sub TemplateObj {
     my $self = shift;
+    my $queue = shift;
 
-    unless ( defined $self->{'TemplateObj'} ) {
-        require RT::Template;
-        $self->{'TemplateObj'} = RT::Template->new( $self->CurrentUser );
-        $self->{'TemplateObj'}->Load( $self->Template );
-    }
-    return ( $self->{'TemplateObj'} );
+    my $res = RT::Template->new( $self->CurrentUser );
+    $res->LoadByName( Queue => $queue, Name => $self->Template );
+    return $res;
 }
 
 =head2 Stage
@@ -575,9 +569,11 @@ sub Prepare {
 
     my $return;
     eval {
-        $self->ActionObj->LoadAction( ScripObj       => $self,
-                                      TicketObj      => $args{'TicketObj'},
-                                      TransactionObj => $args{'TransactionObj'},
+        $self->ActionObj->LoadAction(
+            ScripObj       => $self,
+            TicketObj      => $args{'TicketObj'},
+            TransactionObj => $args{'TransactionObj'},
+            TemplateObj    => $self->TemplateObj( $args{'TicketObj'}->Queue ),
         );
 
         $return = $self->ActionObj->Prepare();
diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index ad6ece2..c401d2d 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -131,9 +131,8 @@ sub Load  {
     }
 
     if (@_) {
-        # Set the template Id to the passed in template
-        my $template = shift;
-        $self->{'Template'} = $template;
+        $RT::Logger->warning("Passing in Template as second argument is deprecated");
+        $self->{'Template'} = shift;
     }
 
     return ($ok, $msg);
@@ -155,7 +154,14 @@ sub LoadAction  {
         @_
     );
 
-    $self->{_TicketObj} = $args{TicketObj};
+    # XXX: this whole block goes with TemplateObj method
+    unless ( @_ && exists $args{'TemplateObj'} ) {
+        local $self->{_TicketObj} = $args{TicketObj};
+        $args{'TemplateObj'} = $self->TemplateObj;
+    }
+    else {
+        $self->{'TemplateObj'} = $args{'TemplateObj'};
+    }
 
     $self->ExecModule =~ /^(\w+)$/;
     my $module = $1;
@@ -164,13 +170,10 @@ sub LoadAction  {
     eval "require $type" || die "Require of $type failed.\n$@\n";
 
     return $self->{'Action'} = $type->new(
-        Argument => $self->Argument,
-        CurrentUser => $self->CurrentUser,
+        %args,
+        Argument       => $self->Argument,
+        CurrentUser    => $self->CurrentUser,
         ScripActionObj => $self,
-        ScripObj => $args{'ScripObj'},
-        TemplateObj => $self->TemplateObj,
-        TicketObj => $args{'TicketObj'},
-        TransactionObj => $args{'TransactionObj'},
     );
 }
 
@@ -183,6 +186,8 @@ Return this action's template object
 
 sub TemplateObj {
     my $self = shift;
+    Carp::carp(__PACKAGE__."::TemplateObj is deprecated");
+
     return undef unless $self->{Template};
     if ( !$self->{'TemplateObj'} ) {
         $self->{'TemplateObj'} = RT::Template->new( $self->CurrentUser );

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


More information about the Rt-commit mailing list