From 4161bf2a07985cf94e3a43302791af62aefc0bfa Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Wed, 4 Feb 2026 16:21:31 +0100 Subject: [PATCH 1/6] Add now-timestamp parameter to simpleSaveChangeHistory --- cron/dailyroutine.php | 11 +++++++---- library/ajax/deleteprofile.php | 5 +++-- library/functions.php | 16 +++++++++------- library/lib/list.php | 14 +++++++++----- library/lib/tools.php | 7 +++++-- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/cron/dailyroutine.php b/cron/dailyroutine.php index 924e4354..27b4bd79 100644 --- a/cron/dailyroutine.php +++ b/cron/dailyroutine.php @@ -25,6 +25,9 @@ FROM people AS p LEFT OUTER JOIN camps AS c ON c.id = p.camp_id WHERE (NOT p.deleted OR p.deleted IS NULL) AND p.parent_id IS NULL'); + + // All deletions are logged with the same timestamp + $now = date('Y-m-d H:i:s'); while ($row = db_fetch($result)) { $row['touch'] = db_value(' SELECT GREATEST(COALESCE(( @@ -48,8 +51,8 @@ $row['diff'] = $date2->diff($date1)->format('%a'); if ($row['diff'] > $row['treshold']) { - db_query('UPDATE people SET deleted = NOW() WHERE id = :id', ['id' => $row['id']]); - simpleSaveChangeHistory('people', $row['id'], 'Record deleted by daily routine'); + db_query('UPDATE people SET deleted = :now WHERE id = :id', ['id' => $row['id'], 'now' => $now]); + simpleSaveChangeHistory('people', $row['id'], 'Record deleted by daily routine', $now); db_touch('people', $row['id']); } } @@ -61,8 +64,8 @@ FROM people AS p1, people AS p2 WHERE p2.parent_id = p1.id AND p1.deleted AND (NOT p2.deleted OR p2.deleted IS NULL)'); while ($row = db_fetch($result)) { - db_query('UPDATE people SET deleted = NOW() WHERE id = :id', ['id' => $row['id']]); - simpleSaveChangeHistory('people', $row['id'], 'Record deleted by daily routine because head of family/beneficiary was deleted'); + db_query('UPDATE people SET deleted = :now WHERE id = :id', ['id' => $row['id'], 'now' => $now]); + simpleSaveChangeHistory('people', $row['id'], 'Record deleted by daily routine because head of family/beneficiary was deleted', $now); db_touch('people', $row['id']); } diff --git a/library/ajax/deleteprofile.php b/library/ajax/deleteprofile.php index 4e72a5a5..30d98582 100644 --- a/library/ajax/deleteprofile.php +++ b/library/ajax/deleteprofile.php @@ -1,14 +1,15 @@ after the @ symbol (e.g., user@domain.com.deleted.123) - db_query('UPDATE cms_users SET deleted = NOW(), email = CONCAT(email,".deleted.",id) WHERE id = :id AND (NOT deleted OR deleted IS NULL) AND email NOT REGEXP "@.*\.deleted\.[0-9]+$"', ['id' => $_POST['cms_user_id']]); + db_query('UPDATE cms_users SET deleted = :now, email = CONCAT(email,".deleted.",id) WHERE id = :id AND (NOT deleted OR deleted IS NULL) AND email NOT REGEXP "@.*\.deleted\.[0-9]+$"', ['now' => $now, 'id' => $_POST['cms_user_id']]); updateAuth0UserFromDb($_POST['cms_user_id']); + simpleSaveChangeHistory('cms_users', $_POST['cms_user_id'], 'Record deleted without undelete', $now); }); -simpleSaveChangeHistory('cms_users', $_POST['cms_user_id'], 'Record deleted without undelete'); // when a user deactive its account we need to ensure that user logged out immediately and then redirected to Auth0 login page global $settings; logout(); diff --git a/library/functions.php b/library/functions.php index 8da48bd8..3d44619b 100644 --- a/library/functions.php +++ b/library/functions.php @@ -272,6 +272,7 @@ function move_boxes($ids, $newlocationid, $mobile = false) { [$count, $action_label, $mobile_message] = db_transaction(function () use ($ids, $newlocationid) { $count = 0; + $now = date('Y-m-d H:i:s'); foreach ($ids as $id) { $box = db_row(' SELECT @@ -311,23 +312,24 @@ function move_boxes($ids, $newlocationid, $mobile = false) ' UPDATE stock SET - modified = NOW(), + modified = :now, modified_by = :user_id , location_id = :location WHERE id = :id', - ['location' => $newlocationid, 'id' => $id, 'user_id' => $_SESSION['user']['id']] + ['location' => $newlocationid, 'id' => $id, 'now' => $now, 'user_id' => $_SESSION['user']['id']] ); $from['int'] = $box['location_id']; $to['int'] = $newlocationid; - simpleSaveChangeHistory('stock', $id, 'location_id', $from, $to); + simpleSaveChangeHistory('stock', $id, 'location_id', $now, $from, $to); db_query( ' INSERT INTO itemsout (product_id, size_id, count, movedate, from_location, to_location) - VALUES (:product_id, :size_id, :count, NOW(), :from_location, :to_location)', + VALUES (:product_id, :size_id, :count, :now, :from_location, :to_location)', ['product_id' => $box['product_id'], 'size_id' => $box['size_id'], 'count' => $box['items'], + 'now' => $now, 'from_location' => $box['location_id'], 'to_location' => $newlocationid, ] ); @@ -343,12 +345,12 @@ function move_boxes($ids, $newlocationid, $mobile = false) UPDATE stock SET box_state_id = :box_state_id, - modified = NOW(), + modified = :now, modified_by = :user_id WHERE id = :id', - ['box_state_id' => $newlocation['box_state_id'], 'id' => $id, 'user_id' => $_SESSION['user']['id']] + ['box_state_id' => $newlocation['box_state_id'], 'id' => $id, 'now' => $now, 'user_id' => $_SESSION['user']['id']] ); - simpleSaveChangeHistory('stock', $id, 'box_state_id', $from, $to); + simpleSaveChangeHistory('stock', $id, 'box_state_id', $now, $from, $to); $mobile_message .= ' and its state changed to '.$newlocation['box_state_name']; } diff --git a/library/lib/list.php b/library/lib/list.php index 1bb50ebb..e50d1872 100644 --- a/library/lib/list.php +++ b/library/lib/list.php @@ -98,11 +98,12 @@ function listRealDelete($table, $ids, $uri = false) $hasPrevent = db_fieldexists($table, 'preventdelete'); $hasTree = db_fieldexists($table, 'parent_id'); $count = 0; + $now = date('Y-m-d H:i:s'); foreach ($ids as $id) { $result = db_query('DELETE FROM '.$table.' WHERE id = :id'.($hasPrevent ? ' AND NOT preventdelete' : ''), ['id' => $id]); $count += $result->rowCount(); if ($result->rowCount()) { - simpleSaveChangeHistory($table, $id, 'Record deleted without undelete'); + simpleSaveChangeHistory($table, $id, 'Record deleted without undelete', $now); } } @@ -232,16 +233,18 @@ function listDeleteAction($table, $id, $count = 0, $recursive = false) // prevent deletion of deleted records $hasDeleted = db_fieldexists($table, 'deleted'); - $query = 'UPDATE '.$table.' SET deleted = NOW(), modified = NOW(), modified_by = :user_id WHERE id = :id'; + $now = date('Y-m-d H:i:s'); + $query = 'UPDATE '.$table.' SET deleted = :now, modified = :now, modified_by = :user_id WHERE id = :id'; $query .= ($hasPrevent ? ' AND NOT preventdelete' : ''); $query .= ($hasDeleted ? ' AND (NOT deleted OR deleted IS NULL)' : ''); $result = db_query($query, [ + 'now' => $now, 'id' => $id, 'user_id' => $_SESSION['user']['id'], ]); $count += $result->rowCount(); if (1 === $result->rowCount()) { - simpleSaveChangeHistory($table, $id, 'Record deleted'); + simpleSaveChangeHistory($table, $id, 'Record deleted', $now); } if ($recursive) { @@ -283,10 +286,11 @@ function listUndelete($table, $ids, $uri = false, $overwritehastree = false) function listUnDeleteAction($table, $id, $count = 0, $recursive = false, $null = true) { - $result = db_query('UPDATE '.$table.' SET deleted = '.($null ? 'NULL' : '0').', modified = NOW(), modified_by = :user_id WHERE id = :id', ['id' => $id, 'user_id' => $_SESSION['user']['id']]); + $now = date('Y-m-d H:i:s'); + $result = db_query('UPDATE '.$table.' SET deleted = '.($null ? 'NULL' : '0').', modified = :now, modified_by = :user_id WHERE id = :id', ['now' => $now, 'id' => $id, 'user_id' => $_SESSION['user']['id']]); $count += $result->rowCount(); if ($result->rowCount()) { - simpleSaveChangeHistory($table, $id, 'Record recovered'); + simpleSaveChangeHistory($table, $id, 'Record recovered', $now); } if ($recursive) { diff --git a/library/lib/tools.php b/library/lib/tools.php index 02ed012b..c1c76b89 100644 --- a/library/lib/tools.php +++ b/library/lib/tools.php @@ -286,13 +286,16 @@ function utf8_decode_array($array) return $array; } -function simpleSaveChangeHistory($table, $record, $changes, $from = [], $to = []) +function simpleSaveChangeHistory($table, $record, $changes, $now = null, $from = [], $to = []) { // from and to variable must be arrays with entry 'int' or 'float' if (!db_tableexists('history')) { return; } - db_query('INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate, from_int, from_float, to_int, to_float) VALUES (:table,:id,:change,:user_id,:ip,NOW(), :from_int, :from_float, :to_int, :to_float)', ['table' => $table, 'id' => $record, 'change' => $changes, 'user_id' => $_SESSION['user']['id'], 'ip' => $_SERVER['REMOTE_ADDR'], 'from_int' => $from['int'], 'from_float' => $from['float'], 'to_int' => $to['int'], 'to_float' => $to['float']]); + if (null === $now) { + $now = date('Y-m-d H:i:s'); + } + db_query('INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate, from_int, from_float, to_int, to_float) VALUES (:table,:id,:change,:user_id,:ip,:now, :from_int, :from_float, :to_int, :to_float)', ['table' => $table, 'id' => $record, 'change' => $changes, 'user_id' => $_SESSION['user']['id'], 'ip' => $_SERVER['REMOTE_ADDR'], 'now' => $now, 'from_int' => $from['int'], 'from_float' => $from['float'], 'to_int' => $to['int'], 'to_float' => $to['float']]); } function simpleBulkSaveChangeHistory($table, $records, $changes, $from = [], $to = []) From 0a1a05b3548bfa0f33d79dcfb8b7e71ed1411b4f Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Wed, 4 Feb 2026 18:16:39 +0100 Subject: [PATCH 2/6] Account for recursive listDeleteAction and listUndeleteAction --- library/lib/list.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/library/lib/list.php b/library/lib/list.php index e50d1872..90ea40b0 100644 --- a/library/lib/list.php +++ b/library/lib/list.php @@ -148,6 +148,7 @@ function listDelete($table, $ids, $uri = false, $fktables = null, $saveHistory = $hasPrevent = db_fieldexists($table, 'preventdelete'); $hasTree = db_fieldexists($table, 'parent_id'); $count = 0; + $now = date('Y-m-d H:i:s'); try { foreach ($ids as $id) { @@ -182,12 +183,12 @@ function listDelete($table, $ids, $uri = false, $fktables = null, $saveHistory = } } } - $count += listDeleteAction($table, $id, 0, $hasTree); + $count += listDeleteAction($table, $id, $now, 0, $hasTree); } else { $result = db_query('DELETE FROM '.$table.' WHERE id = :id'.($hasPrevent ? ' AND NOT preventdelete' : ''), ['id' => $id]); $count += $result->rowCount(); if ($result->rowCount() && $saveHistory) { - simpleSaveChangeHistory($table, $id, 'Record deleted'); + simpleSaveChangeHistory($table, $id, 'Record deleted', $now); } } } @@ -227,13 +228,12 @@ function listDeleteMessage($table, $id, $foreignkey, $restricted) return 'This '.$table_name[$table].' cannot be removed since '.$object_table_name[$foreignkey['TABLE_NAME']].''.$object_name.' '.$id_name.' is still active. Please edit or remove it first!'; } -function listDeleteAction($table, $id, $count = 0, $recursive = false) +function listDeleteAction($table, $id, $now, $count = 0, $recursive = false) { $hasPrevent = db_fieldexists($table, 'preventdelete'); // prevent deletion of deleted records $hasDeleted = db_fieldexists($table, 'deleted'); - $now = date('Y-m-d H:i:s'); $query = 'UPDATE '.$table.' SET deleted = :now, modified = :now, modified_by = :user_id WHERE id = :id'; $query .= ($hasPrevent ? ' AND NOT preventdelete' : ''); $query .= ($hasDeleted ? ' AND (NOT deleted OR deleted IS NULL)' : ''); @@ -250,7 +250,7 @@ function listDeleteAction($table, $id, $count = 0, $recursive = false) if ($recursive) { $childs = db_array('SELECT id FROM '.$table.' WHERE parent_id = :id'.($hasPrevent ? ' AND NOT preventdelete' : ''), ['id' => $id]); foreach ($childs as $child) { - $count += listDeleteAction($table, $child['id'], $count, true); + $count += listDeleteAction($table, $child['id'], $now, $count, true); } } @@ -262,6 +262,7 @@ function listUndelete($table, $ids, $uri = false, $overwritehastree = false) global $translate, $action; $count = 0; + $now = date('Y-m-d H:i:s'); $hasDeletefield = db_fieldexists($table, 'deleted'); $hasPrevent = db_fieldexists($table, 'preventdelete'); @@ -273,7 +274,7 @@ function listUndelete($table, $ids, $uri = false, $overwritehastree = false) foreach ($ids as $id) { if ($hasDeletefield) { - $count += listUndeleteAction($table, $id, 0, $hasTree, db_nullable($table, 'deleted')); + $count += listUndeleteAction($table, $id, $now, 0, $hasTree, db_nullable($table, 'deleted')); } } @@ -284,9 +285,8 @@ function listUndelete($table, $ids, $uri = false, $overwritehastree = false) return [false, $translate['cms_list_undeleteerror'], false]; } -function listUnDeleteAction($table, $id, $count = 0, $recursive = false, $null = true) +function listUndeleteAction($table, $id, $now, $count = 0, $recursive = false, $null = true) { - $now = date('Y-m-d H:i:s'); $result = db_query('UPDATE '.$table.' SET deleted = '.($null ? 'NULL' : '0').', modified = :now, modified_by = :user_id WHERE id = :id', ['now' => $now, 'id' => $id, 'user_id' => $_SESSION['user']['id']]); $count += $result->rowCount(); if ($result->rowCount()) { @@ -296,7 +296,7 @@ function listUnDeleteAction($table, $id, $count = 0, $recursive = false, $null = if ($recursive) { $childs = db_array('SELECT id FROM '.$table.' WHERE parent_id = :id', ['id' => $id]); foreach ($childs as $child) { - $count += listUnDeleteAction($table, $child['id'], $count, true); + $count += listUndeleteAction($table, $child['id'], $now, $count, true); } } @@ -324,7 +324,7 @@ function listBulkUndelete($table, $ids, $uri = false, $overwritehastree = false) return [false, $translate['cms_list_undeleteerror'], false]; } -function listBulkUnDeleteAction($table, $ids, $count = 0, $hasTree = false) +function listBulkUndeleteAction($table, $ids, $count = 0, $hasTree = false) { [$finalIds, $count] = db_transaction(function () use ($table, $ids, $count, $hasTree) { $finalIds = []; From 6e2357c89baaefcbf97a73dfcbb4ef39d034b351 Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Wed, 4 Feb 2026 18:31:01 +0100 Subject: [PATCH 3/6] Set UTC timezone for PHP application --- php.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/php.ini b/php.ini index e482c7d9..79d8327c 100644 --- a/php.ini +++ b/php.ini @@ -1,3 +1,4 @@ +date.timezone = UTC short_open_tag = On ; the following setting was required for smarty templates in google cloud, ; but is now deprecated with php7.4. In php8.2 seems to work without it, too. From 8819561f4b8b6c4310489e9d852c9a123e1971ea Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Thu, 5 Feb 2026 09:54:28 +0100 Subject: [PATCH 4/6] Remove from/to parameters from simpleBulkSaveChangeHistory --- library/lib/tools.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/lib/tools.php b/library/lib/tools.php index c1c76b89..c3095c79 100644 --- a/library/lib/tools.php +++ b/library/lib/tools.php @@ -298,9 +298,8 @@ function simpleSaveChangeHistory($table, $record, $changes, $now = null, $from = db_query('INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate, from_int, from_float, to_int, to_float) VALUES (:table,:id,:change,:user_id,:ip,:now, :from_int, :from_float, :to_int, :to_float)', ['table' => $table, 'id' => $record, 'change' => $changes, 'user_id' => $_SESSION['user']['id'], 'ip' => $_SERVER['REMOTE_ADDR'], 'now' => $now, 'from_int' => $from['int'], 'from_float' => $from['float'], 'to_int' => $to['int'], 'to_float' => $to['float']]); } -function simpleBulkSaveChangeHistory($table, $records, $changes, $from = [], $to = []) +function simpleBulkSaveChangeHistory($table, $records, $changes) { - // from and to variable must be arrays with entry 'int' or 'float' if (!db_tableexists('history')) { return; } @@ -308,14 +307,14 @@ function simpleBulkSaveChangeHistory($table, $records, $changes, $from = [], $to $params = []; if (is_iterable($records)) { for ($i = 0; $i < sizeof($records); ++$i) { - $query .= "(:table{$i},:id{$i},:change{$i},:user_id{$i},:ip{$i},NOW(), :from_int{$i}, :from_float{$i}, :to_int{$i}, :to_float{$i})"; - $params = array_merge($params, ['table'.$i => $table, 'id'.$i => $records[$i], 'change'.$i => $changes, 'user_id'.$i => $_SESSION['user']['id'], 'ip'.$i => $_SERVER['REMOTE_ADDR'], 'from_int'.$i => $from['int'], 'from_float'.$i => $from['float'], 'to_int'.$i => $to['int'], 'to_float'.$i => $to['float']]); + $query .= "(:table{$i},:id{$i},:change{$i},:user_id{$i},:ip{$i},NOW())"; + $params = array_merge($params, ['table'.$i => $table, 'id'.$i => $records[$i], 'change'.$i => $changes, 'user_id'.$i => $_SESSION['user']['id'], 'ip'.$i => $_SERVER['REMOTE_ADDR']]); if ($i !== sizeof($records) - 1) { $query .= ','; } } } if (strlen($query) > 0) { - db_query("INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate, from_int, from_float, to_int, to_float) VALUES {$query}", $params); + db_query("INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate) VALUES {$query}", $params); } } From 4de464e9a0f3c8e4627022e8aa78f317f8da910f Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Thu, 5 Feb 2026 10:18:32 +0100 Subject: [PATCH 5/6] Add optional now-timestamp parameter to simpleBulkSaveChangeHistory --- include/people.php | 7 ++++--- library/lib/list.php | 9 +++++---- library/lib/tools.php | 9 ++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/people.php b/include/people.php index 2d443867..6a82a8d9 100644 --- a/include/people.php +++ b/include/people.php @@ -514,14 +514,15 @@ function () use ($cmsmain, $data) { case 'touch': $ids = explode(',', (string) $_POST['ids']); $userId = $_SESSION['user']['id']; + $now = date('Y-m-d H:i:s'); // Query speed optimised for 500 records from 6.2 seconds to 0.54 seconds using transaction blocks over UPDATE and bulk inserts - db_transaction(function () use ($ids, $userId) { + db_transaction(function () use ($ids, $userId, $now) { foreach ($ids as $id) { - db_query('UPDATE people SET modified = NOW(), modified_by = :user WHERE id = :id', ['id' => $id, 'user' => $userId]); + db_query('UPDATE people SET modified = :now, modified_by = :user WHERE id = :id', ['id' => $id, 'user' => $userId, 'now' => $now]); } }); // Bulk insert used to insert into history table - simpleBulkSaveChangeHistory('people', $ids, 'Touched'); + simpleBulkSaveChangeHistory('people', $ids, 'Touched', $now); $success = true; $message = 'Selected people have been touched'; diff --git a/library/lib/list.php b/library/lib/list.php index 90ea40b0..0bbeb044 100644 --- a/library/lib/list.php +++ b/library/lib/list.php @@ -326,10 +326,11 @@ function listBulkUndelete($table, $ids, $uri = false, $overwritehastree = false) function listBulkUndeleteAction($table, $ids, $count = 0, $hasTree = false) { - [$finalIds, $count] = db_transaction(function () use ($table, $ids, $count, $hasTree) { + $now = date('Y-m-d H:i:s'); + [$finalIds, $count] = db_transaction(function () use ($table, $ids, $count, $hasTree, $now) { $finalIds = []; foreach ($ids as $id) { - $result = db_query('UPDATE '.$table.' SET deleted = 0, modified = NOW(), modified_by = :user_id WHERE id = :id', ['id' => $id, 'user_id' => $_SESSION['user']['id']]); + $result = db_query('UPDATE '.$table.' SET deleted = 0, modified = :now, modified_by = :user_id WHERE id = :id', ['id' => $id, 'user_id' => $_SESSION['user']['id'], 'now' => $now]); $count += $result->rowCount(); if ($result->rowCount()) { $finalIds[] = $id; @@ -338,7 +339,7 @@ function listBulkUndeleteAction($table, $ids, $count = 0, $hasTree = false) if ($hasTree) { $childs = db_array('SELECT id FROM '.$table.' WHERE parent_id = :id', ['id' => $id]); foreach ($childs as $child) { - $result = db_query('UPDATE '.$table.' SET deleted = 0, modified = NOW(), modified_by = :user_id WHERE id = :id', ['id' => $child['id'], 'user_id' => $_SESSION['user']['id']]); + $result = db_query('UPDATE '.$table.' SET deleted = 0, modified = :now, modified_by = :user_id WHERE id = :id', ['id' => $child['id'], 'user_id' => $_SESSION['user']['id'], 'now' => $now]); $count += $result->rowCount(); if ($result->rowCount()) { $finalIds[] = $child['id']; @@ -350,7 +351,7 @@ function listBulkUndeleteAction($table, $ids, $count = 0, $hasTree = false) return [$finalIds, $count]; }); - simpleBulkSaveChangeHistory($table, $finalIds, 'Record recovered'); + simpleBulkSaveChangeHistory($table, $finalIds, 'Record recovered', $now); return $count; } diff --git a/library/lib/tools.php b/library/lib/tools.php index c3095c79..47705ab2 100644 --- a/library/lib/tools.php +++ b/library/lib/tools.php @@ -298,16 +298,19 @@ function simpleSaveChangeHistory($table, $record, $changes, $now = null, $from = db_query('INSERT INTO history (tablename, record_id, changes, user_id, ip, changedate, from_int, from_float, to_int, to_float) VALUES (:table,:id,:change,:user_id,:ip,:now, :from_int, :from_float, :to_int, :to_float)', ['table' => $table, 'id' => $record, 'change' => $changes, 'user_id' => $_SESSION['user']['id'], 'ip' => $_SERVER['REMOTE_ADDR'], 'now' => $now, 'from_int' => $from['int'], 'from_float' => $from['float'], 'to_int' => $to['int'], 'to_float' => $to['float']]); } -function simpleBulkSaveChangeHistory($table, $records, $changes) +function simpleBulkSaveChangeHistory($table, $records, $changes, $now = null) { if (!db_tableexists('history')) { return; } + if (null === $now) { + $now = date('Y-m-d H:i:s'); + } $query = ''; - $params = []; + $params = ['now' => $now]; if (is_iterable($records)) { for ($i = 0; $i < sizeof($records); ++$i) { - $query .= "(:table{$i},:id{$i},:change{$i},:user_id{$i},:ip{$i},NOW())"; + $query .= "(:table{$i},:id{$i},:change{$i},:user_id{$i},:ip{$i},:now)"; $params = array_merge($params, ['table'.$i => $table, 'id'.$i => $records[$i], 'change'.$i => $changes, 'user_id'.$i => $_SESSION['user']['id'], 'ip'.$i => $_SERVER['REMOTE_ADDR']]); if ($i !== sizeof($records) - 1) { $query .= ','; From 0979fa60ec9d05f9ccd181ab26d9d7bc513ebc81 Mon Sep 17 00:00:00 2001 From: Philipp Metzner Date: Thu, 5 Feb 2026 10:30:49 +0100 Subject: [PATCH 6/6] Remove unused function listBulkRealDelete is a better version anyways --- library/ajax/testdbdelete.php | 2 +- library/lib/list.php | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/library/ajax/testdbdelete.php b/library/ajax/testdbdelete.php index a370a03c..e3ebfbe4 100644 --- a/library/ajax/testdbdelete.php +++ b/library/ajax/testdbdelete.php @@ -62,7 +62,7 @@ if ('true' == $return) { db_transaction(function () use ($ids, $return) { - [$return, $msg, $redirect] = listRealDelete($_POST['table'], $ids); + [$return, $msg, $redirect] = listBulkRealDelete($_POST['table'], $ids); foreach ($ids as $id) { deleteAuth0User($id); } diff --git a/library/lib/list.php b/library/lib/list.php index 0bbeb044..f8106d95 100644 --- a/library/lib/list.php +++ b/library/lib/list.php @@ -91,29 +91,6 @@ function listBulkMove($table, $ids, $regardparent = true, $hook = '', $updatetra return [true, $return, false, $aftermove]; } -function listRealDelete($table, $ids, $uri = false) -{ - global $translate, $action; - - $hasPrevent = db_fieldexists($table, 'preventdelete'); - $hasTree = db_fieldexists($table, 'parent_id'); - $count = 0; - $now = date('Y-m-d H:i:s'); - foreach ($ids as $id) { - $result = db_query('DELETE FROM '.$table.' WHERE id = :id'.($hasPrevent ? ' AND NOT preventdelete' : ''), ['id' => $id]); - $count += $result->rowCount(); - if ($result->rowCount()) { - simpleSaveChangeHistory($table, $id, 'Record deleted without undelete', $now); - } - } - - if ($count) { - return [true, $translate['cms_list_deletesuccess'], true]; - } - - return [false, $translate['cms_list_deleteerror'], false]; -} - function listBulkRealDelete($table, $ids, $uri = false) { global $translate, $action;