X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FForm.pm;h=74de73833eacd0b4d6cdc38a415998dc4d4b9668;hb=c461ee8ac1d30075d427b1daaaae2f05595a80db;hp=a6b21e2e560d086537b4313b4b0f2dab60f48d25;hpb=b2d2a98c959bad922eb12f74d849d1a6a153b336;p=kivitendo-erp.git diff --git a/SL/Form.pm b/SL/Form.pm index a6b21e2e5..74de73833 100644 --- a/SL/Form.pm +++ b/SL/Form.pm @@ -36,6 +36,9 @@ #====================================================================== package Form; + +#use strict; + use Data::Dumper; use CGI; @@ -54,6 +57,7 @@ use SL::Template; use SL::User; use Template; use List::Util qw(first max min sum); +use List::MoreUtils qw(any); my $standard_dbh; @@ -64,6 +68,62 @@ END { } } +=item _store_value() + +parses a complex var name, and stores it in the form. + +syntax: + $form->_store_value($key, $value); + +keys must start with a string, and can contain various tokens. +supported key structures are: + +1. simple access + simple key strings work as expected + + id => $form->{id} + +2. hash access. + separating two keys by a dot (.) will result in a hash lookup for the inner value + this is similar to the behaviour of java and templating mechanisms. + + filter.description => $form->{filter}->{description} + +3. array+hashref access + + adding brackets ([]) before the dot will cause the next hash to be put into an array. + using [+] instead of [] will force a new array index. this is useful for recurring + data structures like part lists. put a [+] into the first varname, and use [] on the + following ones. + + repeating these names in your template: + + invoice.items[+].id + invoice.items[].parts_id + + will result in: + + $form->{invoice}->{items}->[ + { + id => ... + parts_id => ... + }, + { + id => ... + parts_id => ... + } + ... + ] + +4. arrays + + using brackets at the end of a name will result in a pure array to be created. + note that you mustn't use [+], which is reserved for array+hash access and will + result in undefined behaviour in array context. + + filter.status[] => $form->{status}->[ val1, val2, ... ] + +=cut sub _store_value { $main::lxdebug->enter_sub(2); @@ -71,30 +131,29 @@ sub _store_value { my $key = shift; my $value = shift; - my $curr = $self; + my @tokens = split /((?:\[\+?\])?(?:\.|$))/, $key; - while ($key =~ /\[\+?\]\.|\./) { - substr($key, 0, $+[0]) = ''; + my $curr; - if ($& eq '.') { - $curr->{$`} ||= { }; - $curr = $curr->{$`}; + if (scalar @tokens) { + $curr = \ $self->{ shift @tokens }; + } - } else { - $curr->{$`} ||= [ ]; - if (!scalar @{ $curr->{$`} } || $& eq '[+].') { - push @{ $curr->{$`} }, { }; - } + while (@tokens) { + my $sep = shift @tokens; + my $key = shift @tokens; - $curr = $curr->{$`}->[-1]; - } + $curr = \ $$curr->[++$#$$curr], next if $sep eq '[]'; + $curr = \ $$curr->[max 0, $#$$curr] if $sep eq '[].'; + $curr = \ $$curr->[++$#$$curr] if $sep eq '[+].'; + $curr = \ $$curr->{$key} } - $curr->{$key} = $value; + $$curr = $value; $main::lxdebug->leave_sub(2); - return \$curr->{$key}; + return $curr; } sub _input_to_hash { @@ -107,7 +166,7 @@ sub _input_to_hash { foreach (@pairs) { my ($key, $value) = split(/=/, $_, 2); - $self->_store_value($self->unescape($key), $self->unescape($value)); + $self->_store_value($self->unescape($key), $self->unescape($value)) if ($key); } $main::lxdebug->leave_sub(2); @@ -170,7 +229,7 @@ sub _request_to_hash { substr $line, $-[0], $+[0] - $-[0], ""; } - $previous = $self->_store_value($name, ''); + $previous = $self->_store_value($name, '') if ($name); $self->{FILENAME} = $filename if ($filename); next; @@ -193,6 +252,31 @@ sub _request_to_hash { $main::lxdebug->leave_sub(2); } +sub _recode_recursively { + $main::lxdebug->enter_sub(); + my ($iconv, $param) = @_; + + if (any { ref $param eq $_ } qw(Form HASH)) { + foreach my $key (keys %{ $param }) { + if (!ref $param->{$key}) { + $param->{$key} = $iconv->convert($param->{$key}); + } else { + _recode_recursively($iconv, $param->{$key}); + } + } + + } elsif (ref $param eq 'ARRAY') { + foreach my $idx (0 .. scalar(@{ $param }) - 1) { + if (!ref $param->[$idx]) { + $param->[$idx] = $iconv->convert($param->[$idx]); + } else { + _recode_recursively($iconv, $param->[$idx]); + } + } + } + $main::lxdebug->leave_sub(); +} + sub new { $main::lxdebug->enter_sub(); @@ -219,10 +303,22 @@ sub new { $self->_request_to_hash($_); + my $db_charset = $main::dbcharset; + $db_charset ||= Common::DEFAULT_CHARSET; + + if ($self->{INPUT_ENCODING} && (lc $self->{INPUT_ENCODING} ne $db_charset)) { + require Text::Iconv; + my $iconv = Text::Iconv->new($self->{INPUT_ENCODING}, $db_charset); + + _recode_recursively($iconv, $self); + + delete $self{INPUT_ENCODING}; + } + $self->{action} = lc $self->{action}; $self->{action} =~ s/( |-|,|\#)/_/g; - $self->{version} = "2.6.0 beta 1"; + $self->{version} = "2.6.0"; $main::lxdebug->leave_sub(); @@ -355,28 +451,33 @@ sub unescape { } sub quote { + $main::lxdebug->enter_sub(); my ($self, $str) = @_; if ($str && !ref($str)) { $str =~ s/\"/"/g; } - $str; + $main::lxdebug->leave_sub(); + return $str; } sub unquote { + $main::lxdebug->enter_sub(); my ($self, $str) = @_; if ($str && !ref($str)) { $str =~ s/"/\"/g; } - $str; + $main::lxdebug->leave_sub(); + return $str; } sub hide_form { + $main::lxdebug->enter_sub(); my $self = shift; if (@_) { @@ -387,7 +488,7 @@ sub hide_form { print($main::cgi->hidden("-name" => $_, "-default" => $self->{$_}) . "\n"); } } - + $main::lxdebug->leave_sub(); } sub error { @@ -533,7 +634,7 @@ sub header { return; } - my ($stylesheet, $favicon); + my ($stylesheet, $favicon, $pagelayout); if ($ENV{HTTP_USER_AGENT}) { my $doctype; @@ -591,7 +692,7 @@ sub header { ? "$self->{title} - $self->{titlebar}" : $self->{titlebar}; my $ajax = ""; - foreach $item (@ { $self->{AJAX} }) { + foreach my $item (@ { $self->{AJAX} }) { $ajax .= $item->show_javascript(); } @@ -609,7 +710,7 @@ sub header {