This commit was generated by cvs2svn to compensate for changes in r2523,
[freeside.git] / rt / lib / RT / Template.pm
1 # $Header: /home/cvs/cvsroot/freeside/rt/lib/RT/Template.pm,v 1.1 2002-08-12 06:17:07 ivan Exp $
2 # Copyright 1996-2002 Jesse Vincent <jesse@bestpractical.com>
3 # Portions Copyright 2000 Tobias Brox <tobix@cpan.org> 
4 # Released under the terms of the GNU General Public License
5
6 =head1 NAME
7
8   RT::Template - RT's template object
9
10 =head1 SYNOPSIS
11
12   use RT::Template;
13
14
15 =head1 DESCRIPTION
16
17
18 =head1 METHODS
19
20 =begin testing
21
22 ok(require RT::TestHarness);
23 ok(require RT::Template);
24
25 =end testing
26
27 =cut
28
29 package RT::Template;
30 use RT::Record;
31 use MIME::Entity;
32 use MIME::Parser;
33
34 @ISA = qw(RT::Record);
35
36 # {{{ sub _Init
37
38 sub _Init {
39     my $self = shift;
40     $self->{'table'} = "Templates";
41     return ( $self->SUPER::_Init(@_) );
42 }
43
44 # }}}
45
46 # {{{ sub _Accessible 
47
48 sub _Accessible {
49     my $self = shift;
50     my %Cols = (
51         id            => 'read',
52         Name          => 'read/write',
53         Description   => 'read/write',
54         Type          => 'read/write',    #Type is one of Action or Message
55         Content       => 'read/write',
56         Queue         => 'read/write',
57         Creator       => 'read/auto',
58         Created       => 'read/auto',
59         LastUpdatedBy => 'read/auto',
60         LastUpdated   => 'read/auto'
61     );
62     return $self->SUPER::_Accessible( @_, %Cols );
63 }
64
65 # }}}
66
67 # {{{ sub _Set
68
69 sub _Set {
70     my $self = shift;
71
72     # use super::value or we get acl blocked
73     if ( ( defined $self->SUPER::_Value('Queue') )
74         && ( $self->SUPER::_Value('Queue') == 0 ) )
75     {
76         unless ( $self->CurrentUser->HasSystemRight('ModifyTemplate') ) {
77             return ( 0, 'Permission Denied' );
78         }
79     }
80     else {
81
82         unless ( $self->CurrentUserHasQueueRight('ModifyTemplate') ) {
83             return ( 0, 'Permission Denied' );
84         }
85     }
86     return ( $self->SUPER::_Set(@_) );
87
88 }
89
90 # }}}
91
92 # {{{ sub _Value 
93
94 =head2 _Value
95
96 Takes the name of a table column.
97 Returns its value as a string, if the user passes an ACL check
98
99 =cut
100
101 sub _Value {
102
103     my $self  = shift;
104     my $field = shift;
105
106     #If the current user doesn't have ACLs, don't let em at it.  
107     #use super::value or we get acl blocked
108     if ( ( !defined $self->__Value('Queue') )
109         || ( $self->__Value('Queue') == 0 ) )
110     {
111         unless ( $self->CurrentUser->HasSystemRight('ShowTemplate') ) {
112             return (undef);
113         }
114     }
115     else {
116         unless ( $self->CurrentUserHasQueueRight('ShowTemplate') ) {
117             return (undef);
118         }
119     }
120     return ( $self->__Value($field) );
121
122 }
123
124 # }}}
125
126 # {{{ sub Load
127
128 =head2 Load <identifer>
129
130 Load a template, either by number or by name
131
132 =cut
133
134 sub Load {
135     my $self       = shift;
136     my $identifier = shift;
137
138     if ( !$identifier ) {
139         return (undef);
140     }
141
142     if ( $identifier !~ /\D/ ) {
143         $self->SUPER::LoadById($identifier);
144     }
145     else {
146         $self->LoadByCol( 'Name', $identifier );
147
148     }
149 }
150
151 # }}}
152
153 # {{{ sub LoadGlobalTemplate
154
155 =head2 LoadGlobalTemplate NAME
156
157 Load the global tempalte with the name NAME
158
159 =cut
160
161 sub LoadGlobalTemplate {
162     my $self = shift;
163     my $id   = shift;
164
165     return ( $self->LoadQueueTemplate( Queue => 0, Name => $id ) );
166 }
167
168 # }}}
169
170 # {{{ sub LoadQueueTemplate
171
172 =head2  LoadQueueTemplate (Queue => QUEUEID, Name => NAME)
173
174 Loads the Queue template named NAME for Queue QUEUE.
175
176 =cut
177
178 sub LoadQueueTemplate {
179     my $self = shift;
180     my %args = (
181         Queue => undef,
182         Name  => undef
183     );
184
185     return ( $self->LoadByCols( Name => $args{'Name'}, Queue => {'Queue'} ) );
186
187 }
188
189 # }}}
190
191 # {{{ sub Create
192
193 =head2 Create
194
195 Takes a paramhash of Content, Queue, Name and Description.
196 Name should be a unique string identifying this Template.
197 Description and Content should be the template's title and content.
198 Queue should be 0 for a global template and the queue # for a queue-specific 
199 template.
200
201 Returns the Template's id # if the create was successful. Returns undef for
202 unknown database failure.
203
204
205 =cut
206
207 sub Create {
208     my $self = shift;
209     my %args = (
210         Content     => undef,
211         Queue       => 0,
212         Description => '[no description]',
213         Type => 'Action',    #By default, template are 'Action' templates
214         Name => undef,
215         @_
216     );
217
218     if ( $args{'Queue'} == 0 ) {
219         unless ( $self->CurrentUser->HasSystemRight('ModifyTemplate') ) {
220             return (undef);
221         }
222     }
223     else {
224         my $QueueObj = new RT::Queue( $self->CurrentUser );
225         $QueueObj->Load( $args{'Queue'} ) || return ( 0, 'Invalid queue' );
226
227         unless ( $QueueObj->CurrentUserHasRight('ModifyTemplate') ) {
228             return (undef);
229         }
230     }
231
232     my $result = $self->SUPER::Create(
233         Content => $args{'Content'},
234         Queue   => $args{'Queue'},
235         ,
236         Description => $args{'Description'},
237         Name        => $args{'Name'}
238     );
239
240     return ($result);
241
242 }
243
244 # }}}
245
246 # {{{ sub Delete
247
248 =head2 Delete
249
250 Delete this template.
251
252 =cut
253
254 sub Delete {
255     my $self = shift;
256
257     unless ( $self->CurrentUserHasRight('ModifyTemplate') ) {
258         return ( 0, 'Permission Denied' );
259     }
260
261     return ( $self->SUPER::Delete(@_) );
262 }
263
264 # }}}
265
266 # {{{ sub MIMEObj
267 sub MIMEObj {
268     my $self = shift;
269     return ( $self->{'MIMEObj'} );
270 }
271
272 # }}}
273
274 # {{{ sub Parse 
275
276 =item Parse
277
278  This routine performs Text::Template parsing on thte template and then imports the 
279  results into a MIME::Entity so we can really use it
280  It returns a tuple of (val, message)
281  If val is 0, the message contains an error message
282
283 =cut
284
285 sub Parse {
286     my $self = shift;
287
288     #We're passing in whatever we were passed. it's destined for _ParseContent
289     my $content = $self->_ParseContent(@_);
290
291     #Lets build our mime Entity
292
293     my $parser = MIME::Parser->new();
294     
295     # Do work on the parsed template in memory, rather than on disk
296     $parser->output_to_core(1); 
297
298     ### Should we forgive normally-fatal errors?
299     $parser->ignore_errors(1);
300     $self->{'MIMEObj'} = eval { $parser->parse_data($content) };
301     $error = ( $@ || $parser->last_error );
302
303     if ($error) {
304         $RT::Logger->error("$error");
305         return ( 0, $error );
306     }
307
308     # Unfold all headers
309     $self->{'MIMEObj'}->head->unfold();
310
311     return ( 1, "Template parsed" );
312    
313
314 }
315
316 # }}}
317
318 # {{{ sub _ParseContent
319
320 # Perform Template substitutions on the template
321
322 sub _ParseContent {
323     my $self = shift;
324     my %args = (
325         Argument       => undef,
326         TicketObj      => undef,
327         TransactionObj => undef,
328         @_
329     );
330
331     # Might be subject to change
332     use Text::Template;
333
334     $T::Ticket      = $args{'TicketObj'};
335     $T::Transaction = $args{'TransactionObj'};
336     $T::Argument    = $args{'Argument'};
337     $T::rtname      = $RT::rtname;
338
339     # We need to untaint the content of the template, since we'll be working
340     # with it
341     my $content = $self->Content();
342     $content =~ s/^(.*)$/$1/;
343     $template = Text::Template->new(
344         TYPE   => STRING,
345         SOURCE => $content
346     );
347
348     my $retval = $template->fill_in( PACKAGE => T );
349     return ($retval);
350 }
351
352 # }}}
353
354 # {{{ sub QueueObj
355
356 =head2 QueueObj
357
358 Takes nothing. returns this ticket's queue object
359
360 =cut
361
362 sub QueueObj {
363     my $self = shift;
364     if ( !defined $self->{'queue'} ) {
365         require RT::Queue;
366         $self->{'queue'} = RT::Queue->new( $self->CurrentUser );
367
368         unless ( $self->{'queue'} ) {
369             $RT::Logger->crit(
370                 "RT::Queue->new(" . $self->CurrentUser . ") returned false" );
371             return (undef);
372         }
373         my ($result) = $self->{'queue'}->Load( $self->__Value('Queue') );
374
375     }
376     return ( $self->{'queue'} );
377 }
378
379 # }}}
380
381 # {{{ sub CurrentUserHasQueueRight
382
383 =head2 CurrentUserHasQueueRight
384
385 Helper function to call the template's queue's CurrentUserHasQueueRight with the passed in args.
386
387 =cut
388
389 sub CurrentUserHasQueueRight {
390     my $self = shift;
391     return ( $self->QueueObj->CurrentUserHasRight(@_) );
392 }
393
394 # }}}
395 1;