9 use List::Util qw(reduce);
 
  13   $main::lxdebug->enter_sub();
 
  18   if ($params{mode} && ($params{mode} eq 'ids')) {
 
  19     Common::check_params_x(\%params, [ qw(from_ids to_ids) ]);
 
  22     Common::check_params(\%params, qw(links));
 
  28   if ($params{mode} && ($params{mode} eq 'ids')) {
 
  29     my ($from_to, $to_from) = $params{from_ids} ? qw(from to) : qw(to from);
 
  32     if ('ARRAY' eq ref $params{"${from_to}_ids"}) {
 
  33       $ids{$from_to} = $params{"${from_to}_ids"};
 
  35       $ids{$from_to} = [ grep { $_ } map { $_ * 1 } split m/\s+/, $params{"${from_to}_ids"} ];
 
  38     if (my $num = scalar @{ $ids{$from_to} }) {
 
  39       $ids{$to_from} = [ ($params{"${to_from}_id"}) x $num ];
 
  40       @links         = map { { 'from_table' => $params{from_table},
 
  41                                'from_id'    => $ids{from}->[$_],
 
  42                                'to_table'   => $params{to_table},
 
  43                                'to_id'      => $ids{to}->[$_],      } } (0 .. $num - 1);
 
  47     @links = @{ $params{links} };
 
  51     $main::lxdebug->leave_sub();
 
  55   my $myconfig = \%main::myconfig;
 
  56   my $form     = $main::form;
 
  58   SL::DB->client->with_transaction(sub {
 
  59     my $dbh      = $params{dbh} || SL::DB->client->dbh;
 
  61     my $query    = qq|INSERT INTO record_links (from_table, from_id, to_table, to_id) VALUES (?, ?, ?, ?)|;
 
  62     my $sth      = prepare_query($form, $dbh, $query);
 
  64     foreach my $link (@links) {
 
  65       next if ('HASH' ne ref $link);
 
  66       next if (!$link->{from_table} || !$link->{from_id} || !$link->{to_table} || !$link->{to_id});
 
  68       do_statement($form, $sth, $query, $link->{from_table}, conv_i($link->{from_id}), $link->{to_table}, conv_i($link->{to_id}));
 
  72   }) or do { die SL::DB->client->error };
 
  74   $main::lxdebug->leave_sub();
 
  78   $main::lxdebug->enter_sub();
 
  83   Common::check_params(\%params, [ qw(from_table from_id to_table to_id) ]);
 
  85   my $myconfig   = \%main::myconfig;
 
  86   my $form       = $main::form;
 
  88   my $dbh        = $params{dbh} || $form->get_standard_dbh($myconfig);
 
  93   foreach my $col (qw(from_table from_id to_table to_id)) {
 
  94     next unless ($params{$col});
 
  96     if ('ARRAY' eq ref $params{$col}) {
 
  97       push @conditions, "$col IN (" . join(', ', ('?') x scalar(@{ $params{$col} })) . ")";
 
  98       push @values,     $col =~ m/table/ ? @{ $params{$col} } : map { conv_i($_) } @{ $params{$col} };
 
 101       push @conditions, "$col = ?";
 
 102       push @values,     $col =~ m/table/ ? $params{$col} : conv_i($params{$col});
 
 106   my $query = qq|SELECT from_table, from_id, to_table, to_id
 
 109   if (scalar @conditions) {
 
 110     $query .= qq| WHERE | . join(' AND ', map { "($_)" } @conditions);
 
 113   my $links = selectall_hashref_query($form, $dbh, $query, @values);
 
 115   $main::lxdebug->leave_sub();
 
 117   return wantarray ? @{ $links } : $links;
 
 121   $main::lxdebug->enter_sub();
 
 129   Common::check_params(\%params, [ qw(from_table from_id to_table to_id) ]);
 
 130   Common::check_params(\%params, "via");
 
 132   my @hops = ref $params{via} eq 'ARRAY'
 
 135   unshift @hops, +{ table => $params{from_table}, id => $params{from_id} };
 
 136   push    @hops, +{ table => $params{to_table},   id => $params{to_id} };
 
 138   my $myconfig   = \%main::myconfig;
 
 139   my $form       = $main::form;
 
 141   my $last_hop   = shift @hops;
 
 143   for my $hop (@hops) {
 
 145     my @temp_links = $self->get_links(
 
 146       from_table => $last_hop->{table},
 
 147       from_id    => $last_hop->{id},
 
 148       to_table   => $hop->{table},
 
 152     # short circuit if any of these are empty
 
 153     return wantarray ? () : [] unless scalar @temp_links;
 
 155     push @links, \@temp_links;
 
 159   my $result = reduce {
 
 163         if (   $a->{to_table} eq $b->{from_table}
 
 164             && $a->{to_id}    eq $b->{from_id} ) {
 
 165           +{ from_table => $a->{from_table},
 
 166              from_id    => $a->{from_id},
 
 167              to_table   => $b->{to_table},
 
 168              to_id      => $b->{to_id} }
 
 174   $main::lxdebug->leave_sub();
 
 176   return wantarray ? @{ $result } : $result;
 
 180   $main::lxdebug->enter_sub();
 
 185   Common::check_params(\%params, [ qw(from_table from_id to_table to_id) ]);
 
 187   my $myconfig   = \%main::myconfig;
 
 188   my $form       = $main::form;
 
 190   SL::DB->client->with_transaction(sub {
 
 191     my $dbh        = $params{dbh} || SL::DB->client->dbh;
 
 194     my (@where_tokens, @where_values);
 
 196     for my $col (qw(from_table from_id to_table to_id)) {
 
 197       add_token(\@where_tokens, \@where_values, col => $col, val => $params{$col}) if $params{$col};
 
 200     my $where = @where_tokens ? "WHERE ". join ' AND ', map { "($_)" } @where_tokens : '';
 
 201     my $query = "DELETE FROM record_links $where";
 
 203     do_query($form, $dbh, $query, @where_values);
 
 206   }) or die { SL::DB->client->error };
 
 208   $main::lxdebug->leave_sub();
 
 221 SL::RecordLinks - Verlinkung von kivitendo Objekten.
 
 227   my @links = RecordLinks->get_links(
 
 232   my @links = RecordLinks->get_links_via(
 
 241   RecordLinks->create_links(
 
 248   RecordLinks->create_links(@links);
 
 254 Transitive RecordLinks mit get_links_via.
 
 256 get_links_via erwartet den zusätzlichen parameter via. via ist ein
 
 257 hashref mit den jeweils optionalen Einträgen table und id, die sich
 
 258 genauso verhalten wie die from/to_table/id werte der get_links funktion.
 
 260 Alternativ kann via auch ein Array dieser Hashes sein:
 
 267       table      => 'delivery_orders'
 
 280 Die Einträge in einem via-Array werden exakt in dieser Reihenfolge
 
 281 benutzt und sind nicht optional. Da obige Beispiel würde also die
 
 284   oe:11 -> ar:12 -> is:13 -> do:14
 
 288   oe:11 -> ar:13 -> do:14