rt 4.0.23
[freeside.git] / rt / lib / RT / Template.pm
index e509454..ecf0946 100755 (executable)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -256,7 +256,7 @@ sub Create {
         $args{'Queue'} = $QueueObj->Id;
     }
 
-    my $result = $self->SUPER::Create(
+    my ( $result, $msg ) = $self->SUPER::Create(
         Content     => $args{'Content'},
         Queue       => $args{'Queue'},
         Description => $args{'Description'},
@@ -264,7 +264,11 @@ sub Create {
         Type        => $args{'Type'},
     );
 
-    return ($result);
+    if ( wantarray ) {
+        return ( $result, $msg );
+    } else {
+        return ( $result );
+    }
 
 }
 
@@ -303,10 +307,9 @@ sub IsEmpty {
 Returns L<MIME::Entity> object parsed using L</Parse> method. Returns
 undef if last call to L</Parse> failed or never be called.
 
-Note that content of the template is UTF-8, but L<MIME::Parser> is not
-good at handling it and all data of the entity should be treated as
-octets and converted to perl strings using Encode::decode_utf8 or
-something else.
+Note that content of the template is characters, but the contents of all
+L<MIME::Entity> objects (including the one returned by this function,
+are bytes in UTF-8.
 
 =cut
 
@@ -335,7 +338,7 @@ sub Parse {
     my ($rv, $msg);
 
 
-    if ($self->Content =~ m{^Content-Type:\s+text/html\b}im) {
+    if (not $self->IsEmpty and $self->Content =~ m{^Content-Type:\s+text/html\b}im) {
         local $RT::Transaction::PreferredContentType = 'text/html';
         ($rv, $msg) = $self->_Parse(@_);
     }
@@ -380,8 +383,8 @@ sub _Parse {
 
     ### Should we forgive normally-fatal errors?
     $parser->ignore_errors(1);
-    # MIME::Parser doesn't play well with perl strings
-    utf8::encode($content);
+    # Always provide bytes, not characters, to MIME objects
+    $content = Encode::encode( 'UTF-8', $content );
     $self->{'MIMEObj'} = eval { $parser->parse_data( \$content ) };
     if ( my $error = $@ || $parser->last_error ) {
         $RT::Logger->error( "$error" );
@@ -458,7 +461,7 @@ sub _ParseContentPerl {
     foreach my $key ( keys %{ $args{TemplateArgs} } ) {
         my $val = $args{TemplateArgs}{ $key };
         next unless ref $val;
-        next if ref $val =~ /^(ARRAY|HASH|SCALAR|CODE)$/;
+        next if ref($val) =~ /^(ARRAY|HASH|SCALAR|CODE)$/;
         $args{TemplateArgs}{ $key } = \$val;
     }
 
@@ -466,6 +469,12 @@ sub _ParseContentPerl {
         TYPE   => 'STRING',
         SOURCE => $args{Content},
     );
+    my ($ok) = $template->compile;
+    unless ($ok) {
+        $RT::Logger->error("Template parsing error in @{[$self->Name]} (#@{[$self->id]}): $Text::Template::ERROR");
+        return ( undef, $self->loc('Template parsing error: [_1]', $Text::Template::ERROR) );
+    }
+
     my $is_broken = 0;
     my $retval = $template->fill_in(
         HASH => $args{TemplateArgs},
@@ -592,17 +601,17 @@ sub _DowngradeFromHTML {
 
     require HTML::FormatText;
     require HTML::TreeBuilder;
-    require Encode;
-    # need to decode_utf8, see the doc of MIMEObj method
+    # MIME objects are always bytes, not characters
     my $tree = HTML::TreeBuilder->new_from_content(
-        Encode::decode_utf8($new_entity->bodyhandle->as_string)
+        Encode::decode( 'UTF-8', $new_entity->bodyhandle->as_string)
     );
-    $new_entity->bodyhandle(MIME::Body::InCore->new(
-        \(scalar HTML::FormatText->new(
-            leftmargin  => 0,
-            rightmargin => 78,
-        )->format( $tree ))
-    ));
+    my $text = HTML::FormatText->new(
+        leftmargin  => 0,
+        rightmargin => 78,
+    )->format( $tree );
+    $text = Encode::encode( "UTF-8", $text );
+
+    $new_entity->bodyhandle(MIME::Body::InCore->new( \$text ));
     $tree->delete;
 
     $orig_entity->add_part($new_entity, 0); # plain comes before html
@@ -731,10 +740,14 @@ sub CompileCheck {
 sub CurrentUserCanRead {
     my $self =shift;
 
-    return 1 if $self->CurrentUserHasQueueRight('ShowTemplate');
-
-    return $self->CurrentUser->HasRight( Right =>'ShowGlobalTemplates', Object => $RT::System )
-        if !$self->QueueObj->Id;
+    if ($self->__Value('Queue')) {
+        my $queue = RT::Queue->new( RT->SystemUser );
+        $queue->Load( $self->__Value('Queue'));
+        return 1 if $self->CurrentUser->HasRight( Right => 'ShowTemplate', Object => $queue );
+    } else {
+        return 1 if $self->CurrentUser->HasRight( Right => 'ShowGlobalTemplates', Object => $RT::System );
+        return 1 if $self->CurrentUser->HasRight( Right => 'ShowTemplate',        Object => $RT::System );
+    }
 
     return;
 }