X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FRecord.pm;h=411e9110f4e9b7e54263f0d0f943ff89eb5587f9;hb=5d5e7f7248d786938c08c867c9ad8f855f92c532;hp=fb83faa3fec411e1cd1a647e6a338ed35f6701ee;hpb=0fb307c305e4bc2c9c27dc25a3308beae3a4d33c;p=freeside.git diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index fb83faa3f..411e9110f 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -6,6 +6,7 @@ use vars qw( $AUTOLOAD @ISA @EXPORT_OK $DEBUG %virtual_fields_cache $nowarn_identical $nowarn_classload $no_update_diff $no_check_foreign + @encrypt_payby ); use Exporter; use Carp qw(carp cluck croak confess); @@ -21,6 +22,7 @@ use FS::CurrentUser; use FS::Schema qw(dbdef); use FS::SearchCache; use FS::Msgcat qw(gettext); +use NetAddr::IP; # for validation #use FS::Conf; #dependency loop bs, in install_callback below instead use FS::part_virtual_field; @@ -29,6 +31,8 @@ use Tie::IxHash; @ISA = qw(Exporter); +@encrypt_payby = qw( CARD DCRD CHEK DCHK ); + #export dbdef for now... everything else expects to find it here @EXPORT_OK = qw( dbh fields hfields qsearch qsearchs dbdef jsearch @@ -530,6 +534,11 @@ sub qsearch { && eval 'defined(@FS::'. $table . '::encrypted_fields)' ) { foreach my $record (@return) { foreach my $field (eval '@FS::'. $table . '::encrypted_fields') { + next if $field eq 'payinfo' + && ($record->isa('FS::payinfo_transaction_Mixin') + || $record->isa('FS::payinfo_Mixin') ) + && $record->payby + && !grep { $record->payby eq $_ } @encrypt_payby; # Set it directly... This may cause a problem in the future... $record->setfield($field, $record->decrypt($record->getfield($field))); } @@ -998,6 +1007,11 @@ sub insert { && $conf->exists('encryption') ) { foreach my $field (eval '@FS::'. $table . '::encrypted_fields') { + next if $field eq 'payinfo' + && ($self->isa('FS::payinfo_transaction_Mixin') + || $self->isa('FS::payinfo_Mixin') ) + && $self->payby + && !grep { $self->payby eq $_ } @encrypt_payby; $self->{'saved'} = $self->getfield($field); $self->setfield($field, $self->encrypt($self->getfield($field))); } @@ -1278,6 +1292,11 @@ sub replace { && scalar( eval '@FS::'. $new->table . '::encrypted_fields') ) { foreach my $field (eval '@FS::'. $new->table . '::encrypted_fields') { + next if $field eq 'payinfo' + && ($new->isa('FS::payinfo_transaction_Mixin') + || $new->isa('FS::payinfo_Mixin') ) + && $new->payby + && !grep { $new->payby eq $_ } @encrypt_payby; $saved->{$field} = $new->getfield($field); $new->setfield($field, $new->encrypt($new->getfield($field))); } @@ -1632,6 +1651,8 @@ Class method for batch imports. Available params: =item fields - Alternate way to specify import, specifying import fields directly as a listref +=item preinsert_callback + =item postinsert_callback =item params @@ -1666,9 +1687,14 @@ sub batch_import { my( $type, $header, $sep_char, $fixedlength_format, $xml_format, $row_callback, @fields ); + my $postinsert_callback = ''; $postinsert_callback = $param->{'postinsert_callback'} if $param->{'postinsert_callback'}; + my $preinsert_callback = ''; + $preinsert_callback = $param->{'preinsert_callback'} + if $param->{'preinsert_callback'}; + if ( $param->{'format'} ) { my $format = $param->{'format'}; @@ -1749,7 +1775,7 @@ sub batch_import { eval "use Parse::FixedLength;"; die $@ if $@; - $parser = new Parse::FixedLength $fixedlength_format; + $parser = Parse::FixedLength->new($fixedlength_format); } else { @@ -1845,15 +1871,20 @@ sub batch_import { next if $line =~ /^\s*$/; #skip empty lines $line = &{$row_callback}($line) if $row_callback; + + next if $line =~ /^\s*$/; #skip empty lines $parser->parse($line) or do { $dbh->rollback if $oldAutoCommit; - return "can't parse: ". $parser->error_input(); + return "can't parse: ". $parser->error_input() . " " . $parser->error_diag; }; @columns = $parser->fields(); } elsif ( $type eq 'fixedlength' ) { + last unless scalar(@buffer); + $line = shift(@buffer); + @columns = $parser->parse($line); } elsif ( $type eq 'xls' ) { @@ -1913,6 +1944,16 @@ sub batch_import { } next if exists( $param->{skiprow} ); + if ( $preinsert_callback ) { + my $error = &{$preinsert_callback}($record, $param); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "preinsert_callback error". ( $line ? " for $line" : '' ). + ": $error"; + } + next if exists $param->{skiprow} && $param->{skiprow}; + } + my $error = $record->insert; if ( $error ) { @@ -2201,7 +2242,7 @@ sub ut_text { #warn "notexist ". \¬exist. "\n"; #warn "AUTOLOAD ". \&AUTOLOAD. "\n"; $self->getfield($field) - =~ /^([µ_0123456789aAáÁàÀâÂåÅäÄãêæÆbBcCçÇdDðÐeEéÉèÈêÊëËfFgGhHiIíÍìÌîÎïÏjJkKlLmMnNñÑoOóÓòÒôÔöÖõÕøغpPqQrRsSßtTuUúÚùÙûÛüÜvVwWxXyYýÝÿzZþÞ \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]\<\>]+)$/ + =~ /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]\<\>]+)$/ or return gettext('illegal_or_empty_text'). " $field: ". $self->getfield($field); $self->setfield($field,$1); @@ -2376,6 +2417,35 @@ sub ut_ipn { } } +=item ut_ip46 COLUMN + +Check/untaint IPv4 or IPv6 address. + +=cut + +sub ut_ip46 { + my( $self, $field ) = @_; + my $ip = NetAddr::IP->new($self->getfield($field)) + or return "Illegal (IP address) $field: ".$self->getfield($field); + $self->setfield($field, lc($ip->addr)); + return ''; +} + +=item ut_ip46n + +Check/untaint IPv6 or IPv6 address. May be null. + +=cut + +sub ut_ip46n { + my( $self, $field ) = @_; + if ( $self->getfield($field) =~ /^$/ ) { + $self->setfield($field, ''); + return ''; + } + $self->ut_ip46($field); +} + =item ut_coord COLUMN [ LOWER [ UPPER ] ] Check/untaint coordinates. @@ -2489,8 +2559,7 @@ May not be null. sub ut_name { my( $self, $field ) = @_; # warn "ut_name allowed alphanumerics: +(sort grep /\w/, map { chr() } 0..255), "\n"; - #$self->getfield($field) =~ /^([\w \,\.\-\']+)$/ - $self->getfield($field) =~ /^([µ_0123456789aAáÁàÀâÂåÅäÄãêæÆbBcCçÇdDðÐeEéÉèÈêÊëËfFgGhHiIíÍìÌîÎïÏjJkKlLmMnNñÑoOóÓòÒôÔöÖõÕøغpPqQrRsSßtTuUúÚùÙûÛüÜvVwWxXyYýÝÿzZþÞ \,\.\-\']+)$/ + $self->getfield($field) =~ /^([\w \,\.\-\']+)$/ or return gettext('illegal_name'). " $field: ". $self->getfield($field); $self->setfield($field,$1); '';