X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Foption_Common.pm;h=8c690890f69cbfe8ce19bb418900824c6d3ea32e;hp=9a44561a0b7c72c0e888c8c7deda1ba0c8a0f4ae;hb=ffa18709ee8a4d05e18d2d406cf73afe79e52524;hpb=2d882de7a5fbca3aa2c793755178b2c138fda04f diff --git a/FS/FS/option_Common.pm b/FS/FS/option_Common.pm index 9a44561a0..8c690890f 100644 --- a/FS/FS/option_Common.pm +++ b/FS/FS/option_Common.pm @@ -1,11 +1,12 @@ package FS::option_Common; use strict; -use vars qw( @ISA $DEBUG ); +use base qw( FS::Record ); +use vars qw( $DEBUG ); +use Carp qw( cluck ); +use Scalar::Util qw( blessed ); use FS::Record qw( qsearch qsearchs dbh ); -@ISA = qw( FS::Record ); - $DEBUG = 0; =head1 NAME @@ -65,7 +66,10 @@ sub insert { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my $error = $self->SUPER::insert; + my $error; + + $error = $self->check_options($options) + || $self->SUPER::insert; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -78,10 +82,13 @@ sub insert { my $valuecol = $self->_option_valuecol; foreach my $optionname ( keys %{$options} ) { + + my $optionvalue = $options->{$optionname}; + my $href = { $pkey => $self->get($pkey), $namecol => $optionname, - $valuecol => $options->{$optionname}, + $valuecol => ( ref($optionvalue) || $optionvalue ), }; #my $option_record = eval "new FS::$option_table \$href"; @@ -91,11 +98,15 @@ sub insert { #} my $option_record = "FS::$option_table"->new($href); - $error = $option_record->insert; + my @args = (); + push @args, $optionvalue if ref($optionvalue); #only hashes supported so far + + $error = $option_record->insert(@args); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; } + } $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -124,13 +135,7 @@ sub delete { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; - - my $error = $self->SUPER::delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; - } - + my $pkey = $self->primary_key; #my $option_table = $self->option_table; @@ -142,6 +147,12 @@ sub delete { } } + my $error = $self->SUPER::delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; @@ -153,22 +164,28 @@ sub delete { Replaces the OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. -If a list hash reference of options is supplied, part_export_option records are -created or modified (see L). +If a list or hash reference of options is supplied, option records are created +or modified. =cut sub replace { my $self = shift; - my $old = ( ref($_[0]) eq ref($self) ) + my $old = ( blessed($_[0]) && $_[0]->isa('FS::Record') ) ? shift : $self->replace_old; - my $options = - ( ref($_[0]) eq 'HASH' ) - ? shift - : { @_ }; + my $options; + my $options_supplied = 0; + if ( ref($_[0]) eq 'HASH' ) { + $options = shift; + $options_supplied = 1; + } else { + $options = { @_ }; + $options_supplied = scalar(@_) ? 1 : 0; + } + warn "FS::option_Common::replace called on $self with options ". join(', ', map "$_ => ". $options->{$_}, keys %$options) if $DEBUG; @@ -184,7 +201,17 @@ sub replace { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my $error = $self->SUPER::replace($old); + my $error; + + if ($options_supplied) { + $error = $self->check_options($options); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + + $error = $self->SUPER::replace($old); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -206,10 +233,15 @@ sub replace { $namecol => $optionname, } ); + my $optionvalue = $options->{$optionname}; + + my %oldhash = $oldopt ? $oldopt->hash : (); + my $href = { + %oldhash, $pkey => $self->get($pkey), $namecol => $optionname, - $valuecol => $options->{$optionname}, + $valuecol => ( ref($optionvalue) || $optionvalue ), }; #my $newopt = eval "new FS::$option_table \$href"; @@ -222,10 +254,15 @@ sub replace { my $opt_pkey = $newopt->primary_key; $newopt->$opt_pkey($oldopt->$opt_pkey) if $oldopt; + + my @args = (); + push @args, $optionvalue if ref($optionvalue); #only hashes supported so far + warn "FS::option_Common::replace: ". ( $oldopt ? "$newopt -> replace($oldopt)" : "$newopt -> insert" ) if $DEBUG > 2; - my $error = $oldopt ? $newopt->replace($oldopt) : $newopt->insert; + my $error = $oldopt ? $newopt->replace($oldopt, @args) + : $newopt->insert( @args); if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -233,13 +270,15 @@ sub replace { } #remove extraneous old options - foreach my $opt ( - grep { !exists $options->{$_->$namecol()} } $old->option_objects - ) { - my $error = $opt->delete; - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return $error; + if ( $options_supplied ) { + foreach my $opt ( + grep { !exists $options->{$_->$namecol()} } $old->option_objects + ) { + my $error = $opt->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } } } @@ -249,6 +288,21 @@ sub replace { } +=item check_options HASHREF + +This method is called by 'insert' and 'replace' to check the options that were supplied. + +Return error-message, or false. + +(In this class, this is a do-nothing routine that always returns false. Override as necessary. No need to call superclass.) + +=cut + +sub check_options { + my ($self, $options) = @_; + ''; +} + =item option_objects Returns all options as FS::I_option objects. @@ -291,13 +345,26 @@ sub option { $pkey => $self->get($pkey), $namecol => shift, }; - warn "$self -> option: searching for ". + cluck "$self -> option: searching for ". join(' / ', map { "$_ => ". $hashref->{$_} } keys %$hashref ) if $DEBUG; my $obj = qsearchs($option_table, $hashref); $obj ? $obj->$valuecol() : ''; } +=item option_cacheable OPTIONNAME + +Same as the option method, but may cache and return a cached value. +Good for use within loops; otherwise, probably avoid. + +=cut + +sub option_cacheable { + my( $self, $name ) = @_; + return $self->{option_cache}{$name} if exists $self->{option_cache}{$name}; + $self->{option_cache}{$name} = $self->option($name,1); +} + sub option_table { my $self = shift;