method trigger documentation in bbn\Appui\History

The function used by the db trigger

This will basically execute the history query if it's configured for.

function(array $cfg) { if ( !self::isEnabled() || !($db = self::_get_db()) ){ return $cfg; } $tables = $cfg['tables'] ?? (array)$cfg['table']; // Will return false if disabled, the table doesn't exist, or doesn't have history if ( ($cfg['kind'] === 'SELECT') && ($cfg['moment'] === 'before') && !empty($cfg['tables']) && !in_array($db->tfn(self::$table), $cfg['tables_full'], true) && !in_array($db->tfn(self::$table_uids), $cfg['tables_full'], true) ){ $change = 0; if ( !isset($cfg['history']) ){ $cfg['history'] = []; $new_join = []; foreach ( $cfg['join'] as $i => $t ){ $post_join = false; $model = $db->modelize($t['table']); if ( isset($model['keys']['PRIMARY']) && ($model['keys']['PRIMARY']['ref_table'] === $db->csn(self::$table_uids)) ){ $change++; if ( $t['type'] !== 'left' ){ $post_join = [ 'table' => $db->tsn(self::$table_uids), 'alias' => $db->tsn(self::$table_uids).$change, 'type' => $t['type'] ?? 'right', 'on' => [ 'conditions' => [ [ 'field' => $db->cfn('bbn_uid', self::$table_uids.$change), 'operator' => 'eq', 'exp' => $db->cfn( $model['keys']['PRIMARY']['columns'][0], !empty($t['alias']) ? $t['alias'] : $t['table'], true ) ], [ 'field' => $db->cfn('bbn_active', self::$table_uids.$change), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ] ]; } else{ $join_alias = $t; $alias = strtolower(Str::genpwd()); $join_alias['alias'] = $alias; $join_alias['on']['conditions'] = $db->replaceTableInConditions($join_alias['on']['conditions'], !empty($t['alias']) ? $t['alias'] : $t['table'], $alias); $new_join[] = $join_alias; $t['on'] = [ 'conditions' => [ [ 'field' => $db->cfn('bbn_uid', self::$table_uids.$change), 'operator' => 'eq', 'exp' => $db->cfn($model['keys']['PRIMARY']['columns'][0], !empty($t['alias']) ? $t['alias'] : $t['table'], true) ], [ 'field' => $db->cfn('bbn_active', self::$table_uids.$change), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ]; $new_join[] = [ 'table' => $db->tsn(self::$table_uids), 'alias' => $db->tsn(self::$table_uids).$change, 'type' => 'left', 'on' => [ 'conditions' => [ [ 'field' => $db->cfn('bbn_uid', self::$table_uids.$change), 'operator' => 'eq', 'exp' => $db->cfn($model['keys']['PRIMARY']['columns'][0], $alias, true) ] ], 'logic' => 'AND' ] ]; } } $new_join[] = $t; if ( $post_join ){ $new_join[] = $post_join; } } foreach ( $cfg['tables'] as $alias => $table ){ $model = $db->modelize($table); if ( isset($model['keys']['PRIMARY']['ref_table']) && ($db->tfn($model['keys']['PRIMARY']['ref_db'].'.'.$model['keys']['PRIMARY']['ref_table']) === self::$table_uids) ){ $change++; $new_join[] = [ 'table' => self::$table_uids, 'alias' => $db->tsn(self::$table_uids).$change, 'on' => [ 'conditions' => [ [ 'field' => $db->cfn(self::$table_uids.$change.'.bbn_uid'), 'operator' => 'eq', 'exp' => $db->cfn($model['keys']['PRIMARY']['columns'][0], \is_string($alias) ? $alias : $table, true) ], [ 'field' => $db->cfn(self::$table_uids.$change.'.bbn_active'), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ] ]; } } if ( $change ){ $cfg['join'] = $new_join; $cfg['where'] = $cfg['filters']; $cfg = $db->reprocessCfg($cfg); } } } if ( $cfg['write'] && ($table = $db->tfn(current($tables))) && ($s = self::getTableCfg($table)) ){ // This happens before the query is executed if ( $cfg['moment'] === 'before' ){ $primary_where = false; $primary_defined = false; $primary_value = false; $idx1 = X::find($cfg['values_desc'], ['primary' => true]); if ( $idx1 !== null ){ $primary_where = $cfg['values'][$idx1]; } $idx = array_search($s['primary'], $cfg['fields'], true); if ( ($idx !== false) && isset($cfg['values'][$idx]) ){ $primary_defined = $cfg['generate_id'] ? false : true; $primary_value = $cfg['values'][$idx]; } switch ( $cfg['kind'] ){ case 'INSERT': // If the primary is specified and already exists in a row in deleted state // (if it exists in active state, DB will return its standard error but it's not this class' problem) if ( !$primary_defined ){ // Checks if there is a unique value (non based on UID) $modelize = $db->modelize($table); $keys = $modelize['keys']; unset($keys['PRIMARY']); foreach ( $keys as $key ){ if ( !empty($key['unique']) && !empty($key['columns']) ){ $fields = []; $exit = false; foreach ( $key['columns'] as $col ){ $col_idx = array_search($col, $cfg['fields'], true); if ( ($col_idx === false) || \is_null($cfg['values'][$col_idx]) ){ $exit = true; break; } else { $fields[] = [ 'field' => $col, 'operator' => 'eq', 'value' => $cfg['values'][$col_idx] ]; } } if ( $exit ){ continue; } self::disable(); if ( $tmp = $db->selectOne([ 'tables' => [$table], 'fields' => [$s['primary']], 'join' => [[ 'table' => self::$table_uids, 'on' => [[ 'field' => $db->cfn('bbn_uid', self::$table_uids), 'operator' => 'eq', 'exp' => $db->cfn($s['primary'], $table, true) ]] ]], 'where' => [ 'conditions' => $fields, 'logic' => 'AND' ] ]) ){ $primary_value = $tmp; $primary_defined = true; self::enable(); break; } self::enable(); } } } if ( $primary_defined && ($db->selectOne(self::$table_uids, self::$column, ['bbn_uid' => $primary_value]) === 0) && //($all = self::$db->rselect($table, [], [$s['primary'] => $primary_value])) ($all = self::$db->rselect([ 'table' => $table, 'fields' => $cfg['fields'], 'join' => [[ 'table' => self::$table_uids, 'on' => [ 'conditions' => [[ 'field' => $s['primary'], 'exp' => 'bbn_uid' ], [ 'field' => self::$column, 'value' => 0 ]] ] ]], 'where' => [ 'conditions' => [[ 'field' => $s['primary'], 'value' => $primary_value ]] ] ])) ){ // We won't execute the after trigger $cfg['trig'] = false; // Real query's execution will be prevented $cfg['run'] = false; $cfg['value'] = 0; /** @var array $update The values to be updated */ $update = []; // We update each element which needs to (the new ones different from the old, and the old ones different from the default) foreach ( $all as $k => $v ){ if ( $k !== $s['primary'] ){ $idx = array_search($k, $cfg['fields'], true); if ( $idx !== false ){ if ( $v !== $cfg['values'][$idx] ){ $update[$k] = $cfg['values'][$idx]; } } else if ( $v !== $s['fields'][$k]['default'] ){ $update[$k] = $s['fields'][$k]['default']; } } } self::disable(); if ( $cfg['value'] = self::$db->update(self::$table_uids, ['bbn_active' => 1], [ ['bbn_uid', '=', $primary_value] ]) ){ // Without this the record won't be write in bbn_history. Added by Mirko $cfg['trig'] = true; // -------- if ( \count($update) > 0 ){ self::enable(); self::$db->update($table, $update, [ $s['primary'] => $primary_value ]); } $cfg['history'][] = [ 'operation' => 'RESTORE', 'column' => $s['fields'][$s['primary']]['id_option'], 'line' => $primary_value, 'chrono' => microtime(true) ]; self::$db->setLastInsertId($primary_value); } self::enable(); } else { self::disable(); if ( $primary_defined && !self::$db->count($table, [$s['primary'] => $primary_value]) ){ $primary_defined = false; } if ( !$primary_defined && self::$db->insertIgnore(self::$table_uids, [ 'bbn_uid' => $primary_value, 'bbn_table' => $s['id'] ]) ){ $cfg['history'][] = [ 'operation' => 'INSERT', 'column' => isset($s['fields'][$s['primary']]) ? $s['fields'][$s['primary']]['id_option'] : null, 'line' => $primary_value, 'chrono' => microtime(true) ]; self::$db->setLastInsertId($primary_value); } self::enable(); } break; case 'UPDATE': // ********** CHANGED BY MIRKO ************* /*if ( $primary_defined ){ $where = [$s['primary'] => $primary_value]; // If the only update regards the history field $row = self::$db->rselect($table, array_keys($cfg['fields']), $where); $time = microtime(true); foreach ( $cfg['values'] as $k => $v ){ if ( ($row[$k] !== $v) && isset($s['fields'][$k]) ){ $cfg['history'][] = [ 'operation' => 'UPDATE', 'column' => $s['fields'][$k]['id_option'], 'line' => $primary_value, 'old' => $row[$k], 'chrono' => $time ]; } } }*/ if ( $primary_where && ($row = self::$db->rselect($table, $cfg['fields'], [$s['primary'] => $primary_where])) ){ $time = microtime(true); foreach ( $cfg['fields'] as $i => $idx ){ $csn = self::$db->csn($idx); if ( array_key_exists($csn, $s['fields']) && ($row[$csn] !== $cfg['values'][$i]) ){ $cfg['history'][] = [ 'operation' => 'UPDATE', 'column' => $s['fields'][$csn]['id_option'], 'line' => $primary_where, 'old' => $row[$csn], 'chrono' => $time ]; } } } // Case where the primary is not defined, we'll update each primary instead else if ( $ids = self::$db->getColumnValues($table, $s['primary'], $cfg['filters']) ){ // We won't execute the after trigger $cfg['trig'] = false; // Real query's execution will be prevented $cfg['run'] = false; $cfg['value'] = 0; $tmp = []; foreach ( $cfg['fields'] as $i => $f ){ $tmp[$f] = $cfg['values'][$i]; } foreach ( $ids as $id ){ $cfg['value'] += self::$db->update($table, $tmp, [$s['primary'] => $id]); } // **************************************** } break; // Nothing is really deleted, the hcol is just set to 0 case 'DELETE': // We won't execute the after trigger $cfg['trig'] = false; // Real query's execution will be prevented $cfg['run'] = false; $cfg['value'] = 0; // Case where the primary is not defined, we'll delete based on each primary instead if ( !$primary_where ){ $ids = self::$db->getColumnValues($table, $s['primary'], $cfg['filters']); foreach ( $ids as $id ){ $cfg['value'] += self::$db->delete($table, [$s['primary'] => $id]); } } else { self::disable(); $cfg['value'] = self::$db->update(self::$table_uids, [ 'bbn_active' => 0 ], [ 'bbn_uid' => $primary_where ]); //var_dump("HIST", $primary_where); self::enable(); if ( $cfg['value'] ){ $cfg['trig'] = 1; // And we insert into the history table $cfg['history'][] = [ 'operation' => 'DELETE', 'column' => $s['fields'][$s['primary']]['id_option'], 'line' => $primary_where, 'old' => NULL, 'chrono' => microtime(true) ]; } } break; } } else if ( ($cfg['moment'] === 'after') && isset($cfg['history']) ){ foreach ($cfg['history'] as $h){ self::_insert($h); } unset($cfg['history']); } } return $cfg; }

The function used by the db trigger BBN is a suite of PHP and JS libraries and VueJS components - all open-source! bbn.io, build applications, the quick way

This website uses cookies to ensure you get the best experience on our website.