Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[kivitendo-erp.git] / SL / Controller / Base.pm
index c63a8ee..42bf6bd 100644 (file)
@@ -5,6 +5,7 @@ use strict;
 use parent qw(Rose::Object);
 
 use Carp;
+use IO::File;
 use List::Util qw(first);
 
 #
@@ -44,6 +45,9 @@ sub render {
   if ($options->{inline}) {
     $source = \$template;
 
+  } elsif($options->{raw}) {
+    $source =  $template;
+
   } else {
     $source = "templates/webpages/${template}." . $options->{type};
     croak "Template file ${source} not found" unless -f $source;
@@ -55,7 +59,7 @@ sub render {
       my $content_type  = $options->{type} eq 'js' ? 'text/javascript' : 'text/html';
 
       print $::form->create_http_response(content_type => $content_type,
-                                          charset      => $::dbcharset || Common::DEFAULT_CHARSET);
+                                          charset      => $::lx_office_conf{system}->{dbcharset} || Common::DEFAULT_CHARSET());
 
     } else {
       $::form->{title} = $locals{title} if $locals{title};
@@ -64,31 +68,46 @@ sub render {
   }
 
   my %params = ( %locals,
-                 AUTH     => $::auth,
-                 FORM     => $::form,
-                 LOCALE   => $::locale,
-                 LXCONFIG => { dbcharset              => $::dbcharset,
-                               webdav                 => $::webdav,
-                               lizenzen               => $::lizenzen,
-                               latex_templates        => $::latex,
-                               opendocument_templates => $::opendocument_templates,
-                               vertreter              => $::vertreter,
-                               show_best_before       => $::show_best_before,
-                             },
-                 LXDEBUG  => $::lxdebug,
-                 MYCONFIG => \%::myconfig,
-                 SELF     => $self,
+                 AUTH          => $::auth,
+                 FLASH         => $::form->{FLASH},
+                 FORM          => $::form,
+                 INSTANCE_CONF => $::instance_conf,
+                 LOCALE        => $::locale,
+                 LXCONFIG      => \%::lx_office_conf,
+                 LXDEBUG       => $::lxdebug,
+                 MYCONFIG      => \%::myconfig,
+                 SELF          => $self,
                );
 
   my $output;
-  my $parser = $self->_template_obj;
-  $parser->process($source, \%params, \$output) || croak $parser->error;
+  if (!$options->{raw}) {
+    my $parser = $self->_template_obj;
+    $parser->process($source, \%params, \$output) || croak $parser->error;
+  } else {
+    $output = $$source;
+  }
 
   print $output unless $options->{inline} || $options->{no_output};
 
   return $output;
 }
 
+sub send_file {
+  my ($self, $file_name, %params) = @_;
+
+  my $file            = IO::File->new($file_name, 'r') || croak("Cannot open file '${file_name}'");
+  my $content_type    =  $params{type} || 'application/octet_stream';
+  my $attachment_name =  $params{name} || $file_name;
+  $attachment_name    =~ s:.*//::g;
+
+  print $::form->create_http_response(content_type        => $content_type,
+                                      content_disposition => 'attachment; filename="' . $attachment_name . '"',
+                                      content_length      => -s $file);
+
+  $::locale->with_raw_io(\*STDOUT, sub { print while <$file> });
+  $file->close;
+}
+
 #
 # Before/after run hooks
 #
@@ -163,9 +182,13 @@ sub _dispatch {
   my $action  = first { $::form->{"action_${_}"} } @actions;
   my $sub     = "action_${action}";
 
-  $self->_run_hooks('before', $action);
-  $self->$sub(@_);
-  $self->_run_hooks('after', $action);
+  if ($self->can($sub)) {
+    $self->_run_hooks('before', $action);
+    $self->$sub(@_);
+    $self->_run_hooks('after', $action);
+  } else {
+    $::form->error($::locale->text('Oops. No valid action found to dispatch. Please report this case to the Lx-Office team.'));
+  }
 }
 
 sub _template_obj {
@@ -179,7 +202,7 @@ sub _template_obj {
                     PLUGIN_BASE  => 'SL::Template::Plugin',
                     INCLUDE_PATH => '.:templates/webpages',
                     COMPILE_EXT  => '.tcc',
-                    COMPILE_DIR  => $::userspath . '/templates-cache',
+                    COMPILE_DIR  => $::lx_office_conf{paths}->{userspath} . '/templates-cache',
                   }) || croak;
 
   return $self->{__basepriv_template_obj};
@@ -306,6 +329,10 @@ containing the template code to interprete. Additionally the output
 will not be sent to the browser. Instead it is only returned to the
 caller.
 
+If C<< $options->{raw}>> is trueish, the function will treat the input as
+already parsed, and will not filter the input through Template. Unlike
+C<inline>, the input is taked as a reference.
+
 If C<< $options->{inline} >> is falsish then C<$template> is
 interpreted as the name of a template file. It is prefixed with
 "templates/webpages/" and postfixed with a file extension based on
@@ -336,9 +363,10 @@ The template itself has access to the following variables:
 
 =item * C<LOCALE> -- C<$::locale>
 
-=item * C<LXCONFIG> -- all parameters from C<config/lx-erp.conf> with
-the same name they appear in the file (e.g. C<dbcharset>, C<webdav>
-etc)
+=item * C<LXCONFIG> -- all parameters from C<config/lx_office.conf>
+with the same name they appear in the file (first level is the
+section, second the actual variable, e.g. C<system.dbcharset>,
+C<features.webdav> etc)
 
 =item * C<LXDEBUG> -- C<$::lxdebug>
 
@@ -373,6 +401,21 @@ browser. Typical use for actions called via AJAX:
   $self->render('todo/single_item', { type => 'js' },
                 item => $employee->most_important_todo_item);
 
+=item C<send_file $file_name, [%params]>
+
+Sends the file C<$file_name> to the browser including appropriate HTTP
+headers for a download. C<%params> can include the following:
+
+=over 2
+
+=item * C<type> -- the file's content type; defaults to
+'application/octet_stream'
+
+=item * C<name> -- the name presented to the browser; defaults to
+C<$file_name>
+
+=back
+
 =item C<url_for $url>
 
 =item C<url_for $params>