/** * The function used by the \bbn\db\connection trigger * This will basically execute the history query if it's configured for. * * @param string $table The table for which the history is called * @param string $kind The type of action: select|update|insert|delete * @param string $moment The moment according to the db action: before|after * @param array $values key/value array of fields names and fields values selected/inserted/updated * @param array $where key/value array of fields names and fields values identifying the row * * @return bool returns true */ public static function trigger($table, $kind, $moment, $values = [], $where = []) { if (self::$enabled && self::check($table)) { $table = self::$db->table_full_name($table); if (!isset(self::$hstructures[$table])) { self::get_table_cfg($table); } if (isset(self::$hstructures[$table], self::$hstructures[$table]['history']) && self::$hstructures[$table]['history']) { $s =& self::$hstructures[$table]; if (!isset($s['primary'])) { \bbn\tools::dump($s); die("You need to have a primary key on a single column in your table {$table} in order to use the history class"); } $date = self::$date ? self::$date : date('Y-m-d H:i:s'); if (count($values) === 1 && array_keys($values)[0] === self::$hcol) { $kind = array_values($values)[0] === 1 ? 'restore' : 'delete'; } switch ($kind) { case 'select': break; case 'insert': if ($moment === 'before' && isset($values[$s['primary']])) { if (self::$db->select_one($table, self::$hcol, [$s['primary'] => $values[$s['primary']]]) === 0) { self::$db->update($table, [self::$hcol = 1], [$s['primary'] => $values[$s['primary']]]); } } else { if ($moment === 'after') { $id = self::$db->last_id(); self::$db->insert(self::$htable, ['operation' => 'INSERT', 'line' => $id, 'column' => $table . '.' . $s['primary'], 'old' => null, 'last_mod' => $date, 'id_user' => self::$huser]); self::$db->set_last_insert_id($id); } } break; case 'restore': if ($moment === 'after') { self::$db->insert(self::$htable, ['operation' => 'RESTORE', 'line' => $where[$s['primary']], 'column' => $table . '.' . self::$hcol, 'old' => '0', 'last_mod' => $date, 'id_user' => self::$huser]); } break; case 'update': if ($moment === 'before') { self::$last_rows = self::$db->rselect_all($table, array_keys($values), $where); } else { if ($moment === 'after') { if (is_array(self::$last_rows)) { foreach (self::$last_rows as $upd) { foreach ($values as $c => $v) { if (!isset($upd[$c])) { $upd[$c] = null; } if ($v !== $upd[$c] && $c !== self::$hcol && isset($s['fields'][$c]['config']['history'])) { self::$db->insert(self::$htable, ['operation' => 'UPDATE', 'line' => $where[$s['primary']], 'column' => $table . '.' . $c, 'old' => $upd[$c], 'last_mod' => $date, 'id_user' => self::$huser]); } } } } else { $id = self::$db->last_id(); self::$db->insert(self::$htable, ['operation' => 'INSERT', 'line' => $id, 'column' => $table . '.' . $s['primary'], 'old' => '', 'last_mod' => $date, 'id_user' => self::$huser]); self::$db->set_last_insert_id($id); } self::$last_rows = false; } } break; case 'delete': if ($moment === 'before') { // Looking for foreign constraints // Nothing is really deleted, the hcol is just set to 0 if ($r = self::$db->query(self::$db->get_update($table, [self::$hcol], $where), 0, array_values($where)[0])) { self::$db->insert(self::$htable, ['operation' => 'DELETE', 'line' => $where[$s['primary']], 'column' => $table . '.' . self::$hcol, 'old' => 1, 'last_mod' => $date, 'id_user' => self::$huser]); return ['trig' => false, 'value' => $r]; /* For each value of this key which is deleted (hopefully one) $to_check = self::$db->get_rows(" SELECT k.`column` AS id, c1.`column` AS to_change, c2.`column` AS from_change, c1.`null`, t.`table` FROM `".self::$admin_db."`.`".self::$prefix."keys` AS k JOIN `".self::$prefix."columns` AS c1 ON c1.`id` LIKE k.`column` JOIN `".self::$prefix."columns` AS c2 ON c2.`id` LIKE k.`ref_column` JOIN `".self::$prefix."tables` AS t ON t.`id` LIKE c1.`table` WHERE k.`ref_column` LIKE ?", $table.'.%%'); $to_select = [self::$primary]; foreach ( $to_check as $c ){ array_push($to_select, $c['from_change']); } // The values from the constrained rows that should have been deleted $delete = self::$db->select_all($table, array_unique($to_select), $where); foreach ( $delete as $del ){ $del = (array) $del; // For each table having a constrain foreach ( $to_check as $c ){ // If it's nullable we set it to null if ( $c['null'] == 1 ){ self::$db->query(" UPDATE `$c[table]` SET `$c[to_change]` = NULL WHERE `$c[to_change]` = ?", $del[$c['from_change']]); } // Then we "delete" it on the same manner self::$db->delete($c['table'], [ $c['to_change'] => $del[$c['from_change']] ], $date); } // Inserting a new history row for each deleted value self::$db->insert(self::$htable, [ 'operation' => 'DELETE', 'line' => $del[$s['primary']], 'column' => $table.'.'.self::$hcol, 'old' => 1, 'last_mod' => $date, 'id_user' => self::$huser]); } * */ } } break; } } } return 1; }
public function run($id_cron = null) { if ($cron = $this->get_next($id_cron)) { $ok = 1; if ($this->is_running($cron['id'])) { $runner = $this->get_runner($cron['id']); $start = strtotime($runner['start']); $timeout = $runner['cfg']['timeout']; if ($start + $timeout > time()) { $this->alert(); } $ok = false; } if ($ok) { $id = $this->start($cron['id']); $output = $this->_exec($cron['file'], $cron['cfg']); $time = $this->finish($id, $output); \bbn\tools::dump("Execution of " . $cron['file'] . " (Journal ID: {$id}) in {$time} secs", $output); return 1; } } }