dbXapp 2.0
RAD, CMS, Module und Runtime-IDE fuer dbXapp
Loading...
Searching...
No Matches
dbxTrace.class.php
Go to the documentation of this file.
1<?php
2namespace dbx\dbxAdmin;
3
4dbx()->get_system_obj('dbxReport', 'use');
5
6class dbxTrace {
7
8 private function action_url($url) {
9 $sep = (strpos((string)$url, '?') === false) ? '?' : '&';
10 return $url . $sep . 'dbx_token=' . rawurlencode(dbx()->action_token('dbxAdmin.trace'));
11 }
12
13 private function check_action_token($work, $oReport) {
14 if (!$work) return true;
15 $token = dbx()->get_modul_var('dbx_token', '', 'varchar|max=128');
16 if (dbx()->check_action_token('dbxAdmin.trace', $token)) return true;
17 $oReport->_msg_err = 'Aktion abgelehnt: Sicherheits-Token fehlt oder ist ungueltig.';
18 dbx()->sys_msg('security', 'dbxAdmin', dbx()->user(), 'invalid admin trace action token', $_SERVER['REQUEST_URI'] ?? '');
19 return false;
20 }
21
22 private function delete_table_action(): string {
23 return '<a class="btn btn-sm btn-outline-danger dbxAjax dbxConfirm"'
24 . ' href="' . dbx()->esc($this->action_url('?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=list_trace&dbx_do=delete_tab')) . '"'
25 . ' title="Trace leeren und optimieren"'
26 . ' data-confirm-title="<i class=\'bi bi-trash3\'></i> Trace leeren und optimieren"'
27 . ' data-confirm="Alle Trace-Eintraege wirklich loeschen und die Tabelle anschliessend optimieren?"'
28 . ' data-confirm-hint="<small>Die Tabelle dbxTrace wird komplett geleert und danach optimiert. Dieser Vorgang kann nicht rueckgaengig gemacht werden.</small>"'
29 . ' data-confirm-buttons="yesno"'
30 . ' role="button"><i class="bi bi-trash3"></i></a>';
31 }
32
33 private $_trace_sys_fields = array(
34 'create_date' => 1,
35 'create_uid' => 1,
36 'update_date' => 1,
37 'update_uid' => 1,
38 'owner' => 1,
39 );
40
41 private function value_to_text($value) {
42 if ($value === null) {
43 return '';
44 }
45
46 if (is_bool($value)) {
47 return $value ? 'true' : 'false';
48 }
49
50 if (is_array($value) || is_object($value)) {
51 return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
52 }
53
54 return (string) $value;
55 }
56
57 private function is_empty_value($value) {
58 if ($value === null) {
59 return true;
60 }
61
62 if (is_string($value) && trim($value) === '') {
63 return true;
64 }
65
66 return false;
67 }
68
69 private function is_trace_sys_field($key) {
70 return isset($this->_trace_sys_fields[$key]);
71 }
72
73 private function get_visible_values($data, $hideEmpty = true) {
74 $values = array();
75 $hiddenSys = 0;
76
77 if (!is_array($data)) {
78 return array($values, $hiddenSys);
79 }
80
81 foreach ($data as $key => $value) {
82 if ($this->is_trace_sys_field($key)) {
83 $hiddenSys++;
84 continue;
85 }
86
87 if ($hideEmpty && $this->is_empty_value($value)) {
88 continue;
89 }
90
91 $values[$key] = $value;
92 }
93
94 return array($values, $hiddenSys);
95 }
96
97 private function make_trace_summary($json, $action) {
98 $data = json_decode((string) $json, true);
99
100 if (!is_array($data)) {
101 return array('summary' => 'Rohdaten', 'fields' => '', 'detail' => (string) $json);
102 }
103
104 $traceAction = $data['action'] ?? $action;
105 $before = $data['before'] ?? null;
106 $delta = $data['delta'] ?? null;
107 $detail = array();
108
109 if ($traceAction == 'delete') {
110 list($values, $hiddenSys) = $this->get_visible_values($before);
111 $count = count($values);
112
113 foreach ($values as $key => $value) {
114 $detail[] = $key . ': ' . $this->value_to_text($value);
115 }
116
117 return array(
118 'summary' => $count ? $count . ' Werte geloescht' : ($hiddenSys ? 'nur Systemfelder' : 'keine Werte'),
119 'fields' => implode(', ', array_slice(array_keys($values), 0, 4)),
120 'detail' => implode("\n", $detail),
121 );
122 }
123
124 if ($traceAction == 'insert') {
125 list($values, $hiddenSys) = $this->get_visible_values($delta);
126 $count = count($values);
127
128 foreach ($values as $key => $value) {
129 $detail[] = $key . ': ' . $this->value_to_text($value);
130 }
131
132 return array(
133 'summary' => $count ? $count . ' Werte gesetzt' : ($hiddenSys ? 'nur Systemfelder' : 'keine Werte'),
134 'fields' => implode(', ', array_slice(array_keys($values), 0, 4)),
135 'detail' => implode("\n", $detail),
136 );
137 }
138
139 if (!is_array($delta)) {
140 return array('summary' => 'keine Aenderung', 'fields' => '', 'detail' => '');
141 }
142
143 if (!is_array($before)) {
144 $before = array();
145 }
146
147 $fields = array();
148 $hiddenSys = 0;
149
150 foreach ($delta as $key => $newValue) {
151 if ($this->is_trace_sys_field($key)) {
152 $hiddenSys++;
153 continue;
154 }
155
156 $fields[] = $key;
157 $oldValue = array_key_exists($key, $before) ? $before[$key] : null;
158 $detail[] = $key . ': ' . $this->value_to_text($oldValue) . ' -> ' . $this->value_to_text($newValue);
159 }
160
161 $count = count($fields);
162
163 return array(
164 'summary' => $count ? $count . ' Felder geaendert' : ($hiddenSys ? 'nur Systemfelder' : 'keine Aenderung'),
165 'fields' => implode(', ', array_slice($fields, 0, 4)),
166 'detail' => implode("\n", $detail),
167 );
168 }
169
170 private function render_trace_json($json, $action) {
171 $summary = $this->make_trace_summary($json, $action);
172 $title = $summary['detail'];
173 $payload = json_decode((string) $json, true);
174
175 if (is_array($payload)) {
176 $context = array();
177
178 if (!empty($payload['source'])) {
179 $context[] = 'source: ' . $payload['source'];
180 }
181
182 if (!empty($payload['modul'])) {
183 $run = $payload['modul'];
184
185 if (!empty($payload['run1'])) $run .= '/' . $payload['run1'];
186 if (!empty($payload['run2'])) $run .= '/' . $payload['run2'];
187 if (!empty($payload['run3'])) $run .= '/' . $payload['run3'];
188
189 $context[] = 'run: ' . $run;
190 }
191
192 if ($context) {
193 $title = implode("\n", $context) . ($title ? "\n\n" . $title : '');
194 }
195 }
196
197 if ($title === '') {
198 $title = $summary['summary'];
199 }
200
201 $html = '<span class="dbx-trace-summary" title="' . dbx()->esc($title) . '">';
202 $html .= '<strong>' . dbx()->esc($summary['summary']) . '</strong>';
203
204 if ($summary['fields']) {
205 $html .= '<span class="dbx-trace-summary-fields">' . dbx()->esc($summary['fields']) . '</span>';
206 }
207
208 $html .= '</span>';
209
210 return $html;
211 }
212
213 public function report_trace_row_action_data($oObj, $data) {
214 if (!is_array($data) || ($data['type'] ?? '') != 'show') {
215 return $data;
216 }
217
218 $record = $data['record'] ?? array();
219
220 if (!is_array($record)) {
221 return $data;
222 }
223
224 $dd = isset($record['dd']) ? urlencode((string) $record['dd']) : '';
225 $rid = isset($record['record_id']) ? urlencode((string) $record['record_id']) : '';
226
227 $data['data']['action'] = '?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=record_history&trace_dd=' . $dd . '&trace_rid=' . $rid;
228 $data['data']['class'] = 'openWin';
229 $data['data']['tooltip'] = 'Historie anzeigen';
230
231 return $data;
232 }
233
234 public function report_trace_body($oObj, $content) {
235 $record = $oObj->get_record();
236 $action = $record['action'] ?? '';
237
238 if (isset($record['action'])) {
239 $badge = 'secondary';
240
241 if ($action == 'insert') $badge = 'success';
242 if ($action == 'update') $badge = 'primary';
243 if ($action == 'delete') $badge = 'danger';
244
245 $record['action'] = '<span class="badge bg-' . $badge . '">' . dbx()->esc($action) . '</span>';
246 }
247
248 if (isset($record['data_json'])) {
249 $record['data_json'] = $this->render_trace_json($record['data_json'], $action);
250 }
251
252 $oObj->_class_body['data_json'] = 'dbx-trace-data';
253 $oObj->set_record($record);
254
255 return $content;
256 }
257
258 private function get_trace_payload($json) {
259 $data = json_decode((string) $json, true);
260
261 return is_array($data) ? $data : array();
262 }
263
264 private function render_history_payload($row) {
265 $payload = $this->get_trace_payload($row['data_json'] ?? '');
266 $before = $payload['before'] ?? array();
267 $delta = $payload['delta'] ?? array();
268 $action = $payload['action'] ?? ($row['action'] ?? '');
269
270 if (!is_array($before)) {
271 $before = array();
272 }
273
274 if (!is_array($delta)) {
275 $delta = array();
276 }
277
278 $html = '<div class="dbx-trace-history-detail">';
279
280 if ($action == 'update') {
281 foreach ($delta as $key => $newValue) {
282 $oldValue = array_key_exists($key, $before) ? $before[$key] : '';
283 $html .= '<div class="dbx-trace-history-row">';
284 $html .= '<strong>' . dbx()->esc($key) . '</strong>';
285 $html .= '<span class="dbx-trace-old">' . dbx()->esc($this->value_to_text($oldValue)) . '</span>';
286 $html .= '<span class="dbx-trace-arrow">&rarr;</span>';
287 $html .= '<span class="dbx-trace-new">' . dbx()->esc($this->value_to_text($newValue)) . '</span>';
288 $html .= '</div>';
289 }
290 } else {
291 $values = ($action == 'delete') ? $before : $delta;
292
293 foreach ($values as $key => $value) {
294 if ($value === null || (is_string($value) && trim($value) === '')) {
295 continue;
296 }
297
298 $html .= '<div class="dbx-trace-history-row">';
299 $html .= '<strong>' . dbx()->esc($key) . '</strong>';
300 $html .= '<span>' . dbx()->esc($this->value_to_text($value)) . '</span>';
301 $html .= '</div>';
302 }
303 }
304
305 $html .= '</div>';
306
307 return $html;
308 }
309
310 private function get_compare_fields($before, $after) {
311 $fields = array();
312
313 if (is_array($before)) {
314 foreach ($before as $key => $value) {
315 $fields[$key] = 1;
316 }
317 }
318
319 if (is_array($after)) {
320 foreach ($after as $key => $value) {
321 $fields[$key] = 1;
322 }
323 }
324
325 return array_keys($fields);
326 }
327
328 private function render_compare_value($value) {
329 $text = $this->value_to_text($value);
330
331 if ($text === '') {
332 return '<span class="dbx-trace-empty">leer</span>';
333 }
334
335 return dbx()->esc($text);
336 }
337
338 private function trace_detail($trace_id) {
339 $row = $this->get_trace_row($trace_id);
340
341 if (!$row) {
342 return '<div class="container-fluid dbxReport dbx-trace-detail"><div class="alert alert-danger">Trace-Eintrag nicht gefunden.</div></div>';
343 }
344
345 $payload = $this->get_trace_payload($row['data_json'] ?? '');
346 $action = $payload['action'] ?? ($row['action'] ?? '');
347 $before = $payload['before'] ?? array();
348 $after = $payload['delta'] ?? array();
349 $source = $payload['source'] ?? '';
350 $modul = $payload['modul'] ?? '';
351 $run1 = $payload['run1'] ?? '';
352 $run2 = $payload['run2'] ?? '';
353 $run3 = $payload['run3'] ?? '';
354
355 if (!is_array($before)) {
356 $before = array();
357 }
358
359 if (!is_array($after)) {
360 $after = array();
361 }
362
363 $fields = $this->get_compare_fields($before, $after);
364
365 $html = '<div class="container-fluid dbxReport dbx-trace-detail">';
366 $html .= '<h3>' . dbx()->esc($row['dd'] ?? '') . ' #' . dbx()->esc($row['record_id'] ?? '') . ' - ' . dbx()->esc($action) . '</h3>';
367 $runPath = $modul;
368 if ($run1) $runPath .= '/' . $run1;
369 if ($run2) $runPath .= '/' . $run2;
370 if ($run3) $runPath .= '/' . $run3;
371
372 $html .= '<div class="mb-2 text-muted">' . dbx()->esc($row['create_date'] ?? '');
373
374 if ($source || $runPath) {
375 $html .= ' | ';
376 if ($source) $html .= 'source: ' . dbx()->esc($source);
377 if ($source && $runPath) $html .= ' | ';
378 if ($runPath) $html .= 'run: ' . dbx()->esc($runPath);
379 }
380
381 $html .= '</div>';
382 $html .= '<table class="table table-striped table-bordered table-light table-hover">';
383 $html .= '<thead><tr><th>Feld</th><th>Vorher</th><th>Nachher</th></tr></thead><tbody>';
384
385 foreach ($fields as $field) {
386 $oldValue = array_key_exists($field, $before) ? $before[$field] : '';
387 $newValue = array_key_exists($field, $after) ? $after[$field] : '';
388
389 if ($action == 'delete') {
390 $newValue = '';
391 }
392
393 $html .= '<tr>';
394 $html .= '<th class="text-nowrap">' . dbx()->esc($field) . '</th>';
395 $html .= '<td class="dbx-trace-before">' . $this->render_compare_value($oldValue) . '</td>';
396 $html .= '<td class="dbx-trace-after">' . $this->render_compare_value($newValue) . '</td>';
397 $html .= '</tr>';
398 }
399
400 if (!count($fields)) {
401 $html .= '<tr><td colspan="3">Keine Feldwerte vorhanden.</td></tr>';
402 }
403
404 $html .= '</tbody></table>';
405 $html .= '<div class="d-flex gap-2 justify-content-end">';
406
407 if ($action == 'delete') {
408 $html .= '<a class="btn btn-primary" href="?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=undelete&trace_id=' . dbx()->esc($row['id'] ?? '') . '">Undelete</a>';
409 } elseif ($action == 'update') {
410 $html .= '<a class="btn btn-primary" href="?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=restore&trace_id=' . dbx()->esc($row['id'] ?? '') . '">Vorherigen Stand wiederherstellen</a>';
411 }
412
413 $html .= '</div>';
414 $html .= '</div>';
415
416 return $html;
417 }
418
419 private function get_trace_row($trace_id) {
420 $db = dbx()->get_system_obj('dbxDB');
421 $rows = $db->select('dbxTrace', array('id' => $trace_id), '*', 'id', 'DESC', '', 1, 0);
422
423 if (is_array($rows) && isset($rows[0])) {
424 return $rows[0];
425 }
426
427 return array();
428 }
429
430 private function restore_trace_before($trace_id) {
431 $db = dbx()->get_system_obj('dbxDB');
432 $row = $this->get_trace_row($trace_id);
433
434 if (!$row) {
435 return '<div class="alert alert-danger">Trace-Eintrag nicht gefunden.</div>';
436 }
437
438 $payload = $this->get_trace_payload($row['data_json'] ?? '');
439 $before = $payload['before'] ?? array();
440 $dd = $row['dd'] ?? '';
441 $rid = $row['record_id'] ?? 0;
442
443 if (!$dd || !$rid || !is_array($before) || !count($before)) {
444 return '<div class="alert alert-warning">Dieser Stand kann nicht wiederhergestellt werden.</div>';
445 }
446
447 $pk = $db->get_dd_primary($dd);
448 if (!$pk) {
449 $pk = 'id';
450 }
451
452 $ok = $db->update($dd, $before, array($pk => $rid));
453
454 if ($ok > 0) {
455 return '<div class="alert alert-success">Stand wurde wiederhergestellt.</div>' . $this->record_history($dd, $rid);
456 }
457
458 return '<div class="alert alert-danger">Stand konnte nicht wiederhergestellt werden.</div>' . $this->record_history($dd, $rid);
459 }
460
461 private function undelete_trace_row($trace_id) {
462 $db = dbx()->get_system_obj('dbxDB');
463 $row = $this->get_trace_row($trace_id);
464
465 if (!$row) {
466 return '<div class="alert alert-danger">Trace-Eintrag nicht gefunden.</div>';
467 }
468
469 $payload = $this->get_trace_payload($row['data_json'] ?? '');
470 $before = $payload['before'] ?? array();
471 $dd = $row['dd'] ?? '';
472 $rid = $row['record_id'] ?? 0;
473
474 if (($row['action'] ?? '') != 'delete' || !$dd || !is_array($before) || !count($before)) {
475 return '<div class="alert alert-warning">Dieser Datensatz kann nicht per Undelete reaktiviert werden.</div>';
476 }
477
478 $ok = $db->insert($dd, $before);
479
480 if ($ok > 0) {
481 return '<div class="alert alert-success">Datensatz wurde reaktiviert.</div>' . $this->record_history($dd, $rid);
482 }
483
484 return '<div class="alert alert-danger">Datensatz konnte nicht reaktiviert werden.</div>' . $this->record_history($dd, $rid);
485 }
486
487 private function record_history($dd = '', $rid = 0) {
488 $db = dbx()->get_system_obj('dbxDB');
489
490 if (!$dd) {
491 $dd = dbx()->get_modul_var('trace_dd', '', 'parameter');
492 }
493
494 if (!$rid) {
495 $rid = dbx()->get_modul_var('trace_rid', 0, 'int');
496 }
497
498 $where = array(
499 'dd' => $dd,
500 'record_id' => $rid,
501 );
502
503 $rows = $db->select('dbxTrace', $where, '*', 'create_date', 'DESC', '', 200, 0);
504
505 if (!is_array($rows)) {
506 $rows = array();
507 }
508
509 $html = '<div class="container-fluid dbxReport dbx-trace-history">';
510 $html .= '<h3>Historie ' . dbx()->esc($dd) . ' #' . dbx()->esc($rid) . '</h3>';
511 $html .= '<table class="table table-striped table-bordered table-light table-hover">';
512 $html .= '<thead><tr><th></th><th>Zeit</th><th>Aktion</th><th>Aenderung</th></tr></thead><tbody>';
513
514 foreach ($rows as $row) {
515 $action = $row['action'] ?? '';
516 $detailUrl = '?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=trace_detail&trace_id=' . urlencode((string) ($row['id'] ?? ''));
517
518 $html .= '<tr>';
519 $html .= '<td class="td-show text-center align-middle">';
520 $html .= '<a class="btn-inline" href="' . dbx()->esc($detailUrl) . '" data-dbx-tooltip="Trace-Detail anzeigen" data-url="' . dbx()->esc($detailUrl) . '" data-title="Trace Detail" data-width="1200" role="button"><i class="bi bi-search"></i></a>';
521 $html .= '</td>';
522 $html .= '<td class="text-nowrap">' . dbx()->esc($row['create_date'] ?? '') . '</td>';
523 $html .= '<td>' . dbx()->esc($action) . '</td>';
524 $html .= '<td>' . $this->render_history_payload($row) . '</td>';
525 $html .= '</tr>';
526 }
527
528 if (!count($rows)) {
529 $html .= '<tr><td colspan="4">Keine Historie gefunden.</td></tr>';
530 }
531
532 $html .= '</tbody></table></div>';
533
534 return $html;
535 }
536
537 private function report_trace() {
538 $dd = 'dbxTrace';
539 $db = dbx()->get_system_obj('dbxDB');
540 $oReport = dbx()->get_system_obj('dbxReport');
541
542 $oReport->init('report-trace');
543 $oReport->_dd = $dd;
544 $oReport->set_tabel_tpl('tpl_row_show', 'dbxAdmin|table_row_trace_show');
545 $oReport->add_rep('bar_actions', $this->delete_table_action());
546
547 $work = dbx()->get_modul_var('dbx_do', '', 'parameter');
548 $rid = dbx()->get_modul_var('rid', 0, 'int');
549 $actionAllowed = $this->check_action_token($work, $oReport);
550
551 if ($actionAllowed && $work == 'row_delete' && $rid) {
552 $ok = $oReport->del_selected($rid);
553 $ok = $db->delete($dd, $rid);
554
555 if ( $ok) $oReport->_msg_success = 'Zeile geloescht';
556 if (!$ok) $oReport->_msg_err = 'Zeile konnte nicht geloescht werden';
557 }
558
559 if ($actionAllowed && $work == 'multi_delete') {
560 $result = $oReport->delete_multi_selected_records($dd);
561 $oReport->apply_multi_delete_result($result);
562 }
563
564 if ($actionAllowed && $work == 'delete_tab') {
565 $ok = $db->delete_tab($dd);
566 $optimizeOk = $ok ? $db->optimize_tab($dd) : 0;
567 dbx()->debug("##delete tab dd=($dd) ok=($ok)");
568 dbx()->debug("##optimize tab dd=($dd) ok=($optimizeOk)");
569 if ($ok && $optimizeOk) $oReport->_msg_success = 'Datenbank-Tabelle geleert und optimiert';
570 if ($ok && !$optimizeOk) $oReport->_msg_success = 'Datenbank-Tabelle geleert. Optimierung konnte nicht ausgefuehrt werden.';
571 if (!$ok) $oReport->_msg_err = 'Datenbank-Tabelle konnte nicht geleert werden';
572 }
573
574 $flds['id'] = 'ID';
575 $flds['create_date'] = 'Create';
576 $flds['action'] = 'Action';
577 $flds['dd'] = 'DD';
578 $flds['record_id'] = 'Record';
579 $flds['owner'] = 'Owner';
580 $flds['data_json'] = 'Aenderung';
581
582 $rformat['create_date'] = 'php-datetime-usr';
583 $rformat['action'] = 'html';
584 $rformat['data_json'] = 'html';
585 $oReport->_rpt_format = $rformat;
586
587 $oReport->_action = '?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=list_trace';
588 $oReport->_action = $this->action_url($oReport->_action);
589 $oReport->_pages = true;
590 $oReport->_create_row_select = true;
591 $oReport->_create_row_edit = false;
592 $oReport->_create_row_show = true;
593 $oReport->_create_row_delete = true;
594 $oReport->_create_sel_flds = true;
595 $oReport->_but_pagination = 5;
596 $oReport->set_callback_owner($this);
597 $oReport->set_body_callback('report_trace_body');
598 $oReport->set_callback('row_action_data', 'report_trace_row_action_data');
599
600 $oReport->enable_delete_tab($dd);
601
602 $oReport->add_action('rows_delete' , 'action_button_delete' , '&dbx_do=multi_delete');
603
604 $oReport->create_selection_fields('dbxAdmin|rpt-trace-selection');
605
606 if ($work != 'delete_tab' && $work != 'multi_delete' && $work != 'row_delete' && $oReport->submit()) {
607 if (!$oReport->errors()) {
608 $oReport->_msg_success = '';
609 } else {
610 $oReport->_msg_err = 'Pruefen sie bitte ihre Eingaben';
611 }
612 }
613
614 $rwhere = $oReport->get_fld_val('dbx_rwhere' , '' , 'sqlsearch|max=64');
615 $rrows = $oReport->get_fld_val('dbx_rrows' , 15 , 'int');
616 $rpos = $oReport->get_fld_val('dbx_rpos' , 0 , 'int');
617 $rsort = $oReport->get_fld_val('dbx_rsort' , 'create_date', 'parameter');
618 $rdesc = $oReport->get_fld_val('dbx_rdesc' , 'DESC' , 'parameter');
619 $select = $oReport->get_fld_val('dbx_rselect', 0 , 'int');
620 $rgroup = '';
621
622 if ($rwhere != '') {
623 $rwhere = array(
624 'search' => array(
625 'value' => $rwhere,
626 'like' => array('action', 'dd', 'data_json'),
627 'equal' => array('record_id', 'owner'),
628 'mode' => 'contains',
629 ),
630 );
631 }
632
633 if ($select) {
634 if (is_array($rwhere)) {
635 $rwhere = $db->normalize_where($dd, $rwhere);
636 }
637
638 $rwhere = $oReport->add_rwhere_select($rwhere);
639 }
640
641 $oReport->_rflds = $flds;
642 $oReport->_rrows = $rrows;
643 $oReport->_rpos = $rpos;
644 $oReport->_count_all = $db->count($dd);
645 $oReport->_rcount = $db->count($dd, $rwhere);
646 $oReport->_rdata = $db->select($dd, $rwhere, $flds, $rsort, $rdesc, $rgroup, $rrows, $rpos);
647
648 return $oReport->run();
649 }
650
651 public function run() {
652 $run2 = dbx()->get_modul_var('dbx_run2', '', 'parameter');
653
654 if ($run2 == 'record_history') {
655 return $this->record_history();
656 }
657
658 if ($run2 == 'trace_detail') {
659 $trace_id = dbx()->get_modul_var('trace_id', 0, 'int');
660 return $this->trace_detail($trace_id);
661 }
662
663 if ($run2 == 'restore') {
664 $trace_id = dbx()->get_modul_var('trace_id', 0, 'int');
665 return $this->restore_trace_before($trace_id);
666 }
667
668 if ($run2 == 'undelete') {
669 $trace_id = dbx()->get_modul_var('trace_id', 0, 'int');
670 return $this->undelete_trace_row($trace_id);
671 }
672
673 return $this->report_trace();
674 }
675}
676?>
report_trace_row_action_data($oObj, $data)
report_trace_body($oObj, $content)
$fields[]
Definition config.dd.php:16
$field
Definition config.dd.php:4
DBX schema administration.
if(! $db->connect_db_server($server)) $result
$_SERVER['REQUEST_URI']