Test auf Übereinstimmung mit regulären Ausdrücken in <%if...%>-Blöcken ohne Berücksic...
[kivitendo-erp.git] / SL / Template.pm
index 4cbde74..6dce41b 100644 (file)
@@ -169,24 +169,27 @@ sub parse_foreach {
 
   my $ary = $self->_get_loop_variable($var, 1, @indices);
 
-  my $sum = 0;
-  my $current_page = 1;
+  my $sum                          = 0;
+  my $current_page                 = 1;
   my ($current_line, $corrent_row) = (0, 1);
+  my $description_array            = $self->_get_loop_variable("description",     1);
+  my $longdescription_array        = $self->_get_loop_variable("longdescription", 1);
+  my $linetotal_array              = $self->_get_loop_variable("linetotal",       1);
+
+  $form->{TEMPLATE_ARRAYS}->{cumulatelinetotal} = [];
 
   for (my $i = 0; $i < scalar(@{$ary}); $i++) {
-    $form->{"__first__"} = $i == 0;
-    $form->{"__last__"} = ($i + 1) == scalar(@{$ary});
-    $form->{"__odd__"} = (($i + 1) % 2) == 1;
+    $form->{"__first__"}   = $i == 1;
+    $form->{"__last__"}    = ($i + 1) == scalar(@{$ary});
+    $form->{"__odd__"}     = (($i + 1) % 2) == 1;
     $form->{"__counter__"} = $i + 1;
 
-    if ((scalar(@{$form->{"description"}}) == scalar(@{$ary})) &&
-        $self->{"chars_per_line"}) {
-      my $lines =
-        int(length($form->{"description"}->[$i]) / $self->{"chars_per_line"});
+    if (scalar @{$description_array} == scalar @{$ary} && $self->{"chars_per_line"} != 0) {
+      my $lines = int(length($description_array->[$i]) / $self->{"chars_per_line"});
       my $lpp;
 
-      $form->{"description"}->[$i] =~ s/(\\newline\s?)*$//;
-      my $_description = $form->{"description"}->[$i];
+      $description_array->[$i] =~ s/(\\newline\s?)*$//;
+      my $_description = $description_array->[$i];
       while ($_description =~ /\\newline/) {
         $lines++;
         $_description =~ s/\\newline//;
@@ -200,7 +203,7 @@ sub parse_foreach {
       }
 
       # Yes we need a manual page break -- or the user has forced one
-      if ((($current_line + $lines) > $lpp) || ($form->{"description"}->[$i] =~ /<pagebreak>/) || ($form->{"longdescription"}->[$i] =~ /<pagebreak>/)) {
+      if ((($current_line + $lines) > $lpp) || ($description_array->[$i] =~ /<pagebreak>/) || ($longdescription_array->[$i] =~ /<pagebreak>/)) {
         my $pb = $self->{"pagebreak_block"};
 
         # replace the special variables <%sumcarriedforward%>
@@ -219,13 +222,13 @@ sub parse_foreach {
       }
       $current_line += $lines;
     }
-    if ($i < scalar(@{$form->{"linetotal"}})) {
-      $sum += $form->parse_amount($self->{"myconfig"},
-                                  $form->{"linetotal"}->[$i]);
+
+    if ($i < scalar(@{$linetotal_array})) {
+      $sum += $form->parse_amount($self->{"myconfig"}, $linetotal_array->[$i]);
     }
-    
-    $form->{"cumulatelinetotal"}[$i] = $form->format_amount($self->{"myconfig"}, $sum, 2);
-    
+
+    $form->{TEMPLATE_ARRAYS}->{cumulatelinetotal}->[$i] = $form->format_amount($self->{"myconfig"}, $sum, 2);
+
     my $new_text = $self->parse_block($text, (@indices, $i));
     return undef unless (defined($new_text));
     $new_contents .= $start_tag . $new_text . $end_tag;
@@ -333,13 +336,38 @@ sub parse_block {
       $new_contents .= $self->substitute_vars(substr($contents, 0, $pos_if), @indices);
       substr($contents, 0, $pos_if) = "";
 
-      if ($contents !~ m|^$self->{tag_start_qm}if\s*(not)?\s+(.*?)$self->{tag_end_qm}|) {
+      if ($contents !~ m/^$self->{tag_start_qm}if
+                         \s*
+                         (not\b|\!)?         # $1 -- Eventuelle Negierung
+                         \s+
+                         (\b.+?\b)           # $2 -- Name der zu überprüfenden Variablen
+                         (                   # $3 -- Beginn des optionalen Vergleiches
+                           \s*
+                           ([!=])            # $4 -- Negierung des Vergleiches speichern
+                           ([=~])            # $5 -- Art des Vergleiches speichern
+                           \s*
+                           (                 # $6 -- Gequoteter String oder Bareword
+                             "(.*?)(?<!\\)"  # $7 -- Gequoteter String -- direkter Vergleich mit eq bzw. ne oder Patternmatching; Escapete Anführungs als Teil des Strings belassen
+                           |
+                             (\b.+?\b)       # $8 -- Bareword -- als Index für $form benutzen
+                           )
+                         )?
+                         \s*
+                         $self->{tag_end_qm}
+                        /x) {
         $self->{"error"} = "Malformed $self->{tag_start}if$self->{tag_end}.";
         $main::lxdebug->leave_sub();
         return undef;
       }
 
-      my ($not, $var) = ($1, $2);
+      my $not           = $1;
+      my $var           = $2;
+      my $operator_neg  = $4; # '=' oder '!' oder undef, wenn kein Vergleich erkannt
+      my $operator_type = $5; # '=' oder '~' für Stringvergleich oder Regex
+      my $quoted_word   = $7; # nur gültig, wenn quoted string angegeben (siehe unten); dann "value" aus <%if var == "value" %>
+      my $bareword      = $8; # undef, falls quoted string angegeben wurde; andernfalls "othervar" aus <%if var == othervar %>
+
+      $not = !$not if ($operator_neg && $operator_neg eq '!');
 
       substr($contents, 0, length($&)) = "";
 
@@ -350,13 +378,22 @@ sub parse_block {
         return undef;
       }
 
-      my $value = $self->{"form"}->{$var};
-      for (my $i = 0; $i < scalar(@indices); $i++) {
-        last unless (ref($value) eq "ARRAY");
-        $value = $value->[$indices[$i]];
+      my $value = $self->_get_loop_variable($var, 0, @indices);
+      my $hit   = 0;
+
+      if ($operator_type) {
+        my $compare_to = $bareword ? $self->_get_loop_variable($bareword, 0, @indices) : $quoted_word;
+        if ($operator_type eq '=') {
+          $hit         = ($not && !($value eq $compare_to))     || (!$not && ($value eq $compare_to));
+        } else {
+          $hit         = ($not && !($value =~ m/$compare_to/i)) || (!$not && ($value =~ m/$compare_to/i));
+        }
+
+      } else {
+        $hit           = ($not && ! $value)                     || (!$not &&  $value);
       }
 
-      if (($not && !$value) || (!$not && $value)) {
+      if ($hit) {
         my $new_text = $self->parse_block($block, @indices);
         if (!defined($new_text)) {
           $main::lxdebug->leave_sub();
@@ -519,8 +556,10 @@ sub convert_to_postscript {
 
   $form->{tmpfile} =~ s/\Q$userspath\E\///g;
 
+  my $latex = $self->_get_latex_path();
+
   for (my $run = 1; $run <= 2; $run++) {
-    system("latex --interaction=nonstopmode $form->{tmpfile} " .
+    system("${latex} --interaction=nonstopmode $form->{tmpfile} " .
            "> $form->{tmpfile}.err");
     if ($?) {
       $self->{"error"} = $form->cleanup();
@@ -558,8 +597,10 @@ sub convert_to_pdf {
 
   $form->{tmpfile} =~ s/\Q$userspath\E\///g;
 
+  my $latex = $self->_get_latex_path();
+
   for (my $run = 1; $run <= 2; $run++) {
-    system("pdflatex --interaction=nonstopmode $form->{tmpfile} " .
+    system("${latex} --interaction=nonstopmode $form->{tmpfile} " .
            "> $form->{tmpfile}.err");
     if ($?) {
       $self->{"error"} = $form->cleanup();
@@ -573,6 +614,10 @@ sub convert_to_pdf {
   $self->cleanup();
 }
 
+sub _get_latex_path {
+  return $main::latex_bin || 'pdflatex';
+}
+
 sub get_mime_type() {
   my ($self) = @_;
 
@@ -1365,7 +1410,7 @@ sub uses_temp_file {
 ####
 ##########################################################
 
-package XMLTemplate; 
+package XMLTemplate;
 
 use vars qw(@ISA);