1 package FS::m2m_Common;
4 use vars qw( @ISA $DEBUG );
5 use FS::Schema qw( dbdef );
6 use FS::Record qw( qsearch qsearchs dbh );
8 #hmm. well. we seem to be used as a mixin.
9 #@ISA = qw( FS::Record );
15 FS::m2m_Common - Mixin class for classes in a many-to-many relationship
21 @ISA = qw( FS::m2m_Common FS::Record );
25 FS::m2m_Common is intended as a mixin class for classes which have a
26 many-to-many relationship with another table (via a linking table).
28 Note: It is currently assumed that the link table contains two fields
29 named the same as the primary keys of ths base and target tables.
35 =item process_m2m OPTION => VALUE, ...
39 link_table (required) -
41 target_table (required) -
43 params (required) - hashref; keys are primary key values in target_table (values are boolean). For convenience, keys may optionally be prefixed with the name
44 of the primary key, as in agentnum54 instead of 54, or passed as an arrayref
50 my( $self, %opt ) = @_;
52 my $self_pkey = $self->dbdef_table->primary_key;
53 my %hash = ( $self_pkey => $self->$self_pkey() );
55 my $link_table = $self->_load_table($opt{'link_table'});
57 my $target_table = $self->_load_table($opt{'target_table'});
58 my $target_pkey = dbdef->table($target_table)->primary_key;
60 if ( ref($opt{'params'}) eq 'ARRAY' ) {
61 $opt{'params'} = { map { $_=>1 } @{$opt{'params'}} };
64 local $SIG{HUP} = 'IGNORE';
65 local $SIG{INT} = 'IGNORE';
66 local $SIG{QUIT} = 'IGNORE';
67 local $SIG{TERM} = 'IGNORE';
68 local $SIG{TSTP} = 'IGNORE';
69 local $SIG{PIPE} = 'IGNORE';
71 my $oldAutoCommit = $FS::UID::AutoCommit;
72 local $FS::UID::AutoCommit = 0;
77 my $targetnum = $_->$target_pkey();
78 ( ! $opt{'params'}->{$targetnum}
79 && ! $opt{'params'}->{"$target_pkey$targetnum"}
82 qsearch( $link_table, \%hash )
84 my $error = $del_obj->delete;
86 $dbh->rollback if $oldAutoCommit;
91 foreach my $add_targetnum (
92 grep { ! qsearchs( $link_table, { %hash, $target_pkey => $_ } ) }
93 map { /^($target_pkey)?(\d+)$/; $2; }
94 grep { /^($target_pkey)?(\d+)$/ }
95 grep { $opt{'params'}->{$_} }
96 keys %{ $opt{'params'} }
99 my $add_obj = "FS::$link_table"->new( {
101 $target_pkey => $add_targetnum,
103 my $error = $add_obj->insert;
105 $dbh->rollback if $oldAutoCommit;
110 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
115 my( $self, $table ) = @_;
116 eval "use FS::$table";
127 # my $target_table = $self->_target_table;
128 # eval "use FS::$target_table";