method trigger documentation in bbn\Db\History

The function used by the db trigger

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

function(array $cfg) { if (!$this->isEnabled()) { 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($this->db->tfn($this->getHistoryTableName()), $cfg['tables_full'], true) && !in_array($this->db->tfn($this->getHistoryUidsTableName()), $cfg['tables_full'], true) ) { $change = 0; if (!isset($cfg['history'])) { $cfg['history'] = []; $new_join = []; foreach ($cfg['join'] as $i => $t){ $post_join = false; $model = $this->db->modelize($t['table']); if (isset($model['keys']['PRIMARY']) && ($model['keys']['PRIMARY']['ref_table'] === $this->db->csn($this->getHistoryUidsTableName())) ) { $change++; if ($t['type'] !== 'left') { $post_join = [ 'table' => $this->db->tsn($this->getHistoryUidsTableName()), 'alias' => $this->db->tsn($this->getHistoryUidsTableName()).$change, 'type' => $t['type'] ?? 'right', 'on' => [ 'conditions' => [ [ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_uid'), $this->getHistoryUidsTableName().$change ), 'operator' => 'eq', 'exp' => $this->db->cfn( $model['keys']['PRIMARY']['columns'][0], !empty($t['alias']) ? $t['alias'] : $t['table'], true ) ], [ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_active'), $this->getHistoryUidsTableName().$change ), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ] ]; } else{ $join_alias = $t; $alias = strtolower(Str::genpwd()); $join_alias['alias'] = $alias; $join_alias['on']['conditions'] = $this->db->replaceTableInConditions($join_alias['on']['conditions'], !empty($t['alias']) ? $t['alias'] : $t['table'], $alias); $new_join[] = $join_alias; $t['on'] = [ 'conditions' => [ [ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_uid'), $this->getHistoryUidsTableName().$change ), 'operator' => 'eq', 'exp' => $this->db->cfn($model['keys']['PRIMARY']['columns'][0], !empty($t['alias']) ? $t['alias'] : $t['table'], true) ], [ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_active'), $this->getHistoryUidsTableName().$change ), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ]; $new_join[] = [ 'table' => $this->db->tsn($this->getHistoryUidsTableName()), 'alias' => $this->db->tsn($this->getHistoryUidsTableName()).$change, 'type' => 'left', 'on' => [ 'conditions' => [ [ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_uid'), $this->getHistoryUidsTableName().$change ), 'operator' => 'eq', 'exp' => $this->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 = $this->db->modelize($table); if (isset($model['keys']['PRIMARY']['ref_table']) && ($this->db->tfn($model['keys']['PRIMARY']['ref_db'].'.'.$model['keys']['PRIMARY']['ref_table']) === $this->getHistoryUidsTableName()) ) { $change++; $new_join[] = [ 'table' => $this->getHistoryUidsTableName(), 'alias' => $this->db->tsn($this->getHistoryUidsTableName()).$change, 'on' => [ 'conditions' => [ [ 'field' => $this->db->cfn( $this->getHistoryUidsTableName().$change.'.'.$this->getHistoryUidsColumnName('bbn_uid') ), 'operator' => 'eq', 'exp' => $this->db->cfn($model['keys']['PRIMARY']['columns'][0], \is_string($alias) ? $alias : $table, true) ], [ 'field' => $this->db->cfn( $this->getHistoryUidsTableName().$change.'.'.$this->getHistoryUidsColumnName('bbn_active') ), 'operator' => '=', 'exp' => '1' ] ], 'logic' => 'AND' ] ]; } } if ($change) { $cfg['join'] = $new_join; $cfg['where'] = $cfg['filters']; $cfg = $this->db->reprocessCfg($cfg); } } } if (isset($cfg['write']) && ($table = $this->db->tfn(current($tables))) && ($s = $this->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 = $this->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; } $this->disable(); if ($tmp = $this->db->selectOne( [ 'tables' => [$table], 'fields' => [$s['primary']], 'join' => [[ 'table' => $this->getHistoryUidsTableName(), 'on' => [[ 'field' => $this->db->cfn( $this->getHistoryUidsColumnName('bbn_uid'), $this->getHistoryUidsTableName() ), 'operator' => 'eq', 'exp' => $this->db->cfn($s['primary'], $table, true) ]] ]], 'where' => [ 'conditions' => $fields, 'logic' => 'AND' ] ] ) ) { $primary_value = $tmp; $primary_defined = true; $this->enable(); break; } $this->enable(); } } } if ($primary_defined && ($this->db->selectOne( $this->getHistoryUidsTableName(), $this->getColumn(), [$this->getHistoryUidsColumnName('bbn_uid') => $primary_value] ) === 0) && ($all = $this->db->rselect( [ 'table' => $table, 'fields' => $cfg['fields'], 'join' => [[ 'table' => $this->getHistoryUidsTableName(), 'on' => [ 'conditions' => [[ 'field' => $s['primary'], 'exp' => 'bbn_uid' ], [ 'field' => $this->getColumn(), '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]; } } elseif ($v !== $s['fields'][$k]['default']) { $update[$k] = $s['fields'][$k]['default']; } } } $this->disable(); if ($cfg['value'] = $this->db->update( $this->getHistoryUidsTableName(), [$this->getHistoryUidsColumnName('bbn_active') => 1], [ [$this->getHistoryUidsColumnName('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) { $this->enable(); $this->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) ]; } $this->enable(); } else { $this->disable(); if ($primary_defined && !$this->db->count($table, [$s['primary'] => $primary_value])) { $primary_defined = false; } if (!$primary_defined && $this->db->insert( $this->getHistoryUidsTableName(), [ $this->getHistoryUidsColumnName('bbn_uid') => $primary_value, $this->getHistoryUidsColumnName('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) ]; $this->db->setLastInsertId($primary_value); } $this->enable(); } break; case 'UPDATE': // ********** CHANGED BY MIRKO ************* if ($primary_where && ($row = $this->db->rselect($table, $cfg['fields'], [$s['primary'] => $primary_where])) ) { $time = microtime(true); foreach ($cfg['fields'] as $i => $idx){ $csn = $this->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 elseif ($ids = $this->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'] += $this->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 = $this->db->getColumnValues($table, $s['primary'], $cfg['filters']); foreach ($ids as $id){ $cfg['value'] += $this->db->delete($table, [$s['primary'] => $id]); } } else { $this->disable(); $cfg['value'] = $this->db->update( $this->getHistoryUidsTableName(), [ $this->getHistoryUidsColumnName('bbn_active') => 0 ], [ $this->getHistoryUidsColumnName('bbn_uid') => $primary_where ] ); //var_dump("HIST", $primary_where); $this->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; } } elseif (($cfg['moment'] === 'after') && isset($cfg['history']) ) { foreach ($cfg['history'] as $h){ $this->_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.