[rt-users] Putting Tags at the End of Subjects

Smylers smylers at gbdirect.co.uk
Tue Mar 26 09:43:12 EST 2002


Earlier in the month I asked about putting tags at the end of subjects,
as I reckoned people would find them less intrusive there than at the
beginning, and attempted to outline how I thought this could work (which
led to Bruce Campbell's Robert J McCloskey paraphrase ...).

I wanted to achieve this in a way such that 'RT' can be upgraded and
provide a new version of RT::Action::SendEmail and I'll automatically
get all the new features, without having to patch each upgrade
separately.

Anyway, I've now done this and got it working.  It could actually be
done slightly more simply than my previous suggestion (and more
correctly too, in the general case).  In case anybody else is interested
in this -- or in overriding particular methods of RT::Action::SendEmail
for some other purpose -- here's the steps:

First create a new module in lib/RT/Action/TagAtEnd.pm consisting of
just these lines:

  package RT::Action::TagAtEnd;

  sub SetSubjectToken {
    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', "$sub $tag");
    }
  }

  1;

Note that that sub is taken in its entirety from RT::Action::SendEmail,
but "$tag $sub" have been swapped.  (That's the bit that puts the tag in
the subject.)

Then create another new module in lib/RT/Action/NotifyTagAtEnd.  This
one is just three lines long:

  package RT::Action::NotifyTagAtEnd;
  use base qw(RT::Action::TagAtEnd RT::Action::Notify);
  1;

What that's saying is to base RT::Action::NotifyTagAtEnd on
RT::Action::TagAtEnd _and_ RT::Action::Notify.  Because of the way
Perl's multiple inheritence rules work, that basically means that
whenever a method gets called on an RT::Action::NotifyTagAtEnd object,
Perl will search in this order:

  1 the module itself -- there aren't any methods here, so this'll
    always fail

  2 RT::Action::TagAtEnd -- the only method there is SetSubjectToken()

  3 RT::Action::Notify -- all of the original methods that actually do
    useful things (this module inherits from RT::Action::SendEmail,
    which provides the original SetSubjectToken(), which won't now be
    invoked).

So from nearly all points of view this new class is the same as
RT::Action::Notify, but one method has been overridden.  This works --
even though RT::Action::TagAtEnd isn't really a class (it doesn't
provide a constructor or anything), it can still have methods inherited
from it in this way.

You'll want lib/RT/Action/NotifyAsCommentTagAtEnd.pm as well:

  package RT::Action::NotifyAsCommentTagAtEnd;
  use base qw(RT::Action::TagAtEnd RT::Action::NotifyAsComment);
  1;

Finally you need to make RT use these new modules instead of your own.
This SQL did it for me with 'MySQL' (concatenation may be different with
other DBMSes):

  UPDATE ScripActions
  SET ExecModule = Concat(ExecModule, 'TagAtEnd')
  WHERE ExecModule like 'Noitfy%'

(I'm sure this would be better with a .insert script, but I haven't yet
got the hang of those.  And anyway that worked.)

That took longer to explain than it did to do.

Cheers.

Smylers
-- 
GBdirect
http://www.gbdirect.co.uk/





More information about the rt-users mailing list