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/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/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/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/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..f8106d95 100644 --- a/library/lib/list.php +++ b/library/lib/list.php @@ -91,28 +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; - 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'); - } - } - - 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; @@ -147,6 +125,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) { @@ -181,12 +160,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); } } } @@ -226,28 +205,29 @@ 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'); - $query = 'UPDATE '.$table.' SET deleted = NOW(), modified = NOW(), modified_by = :user_id WHERE id = :id'; + $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) { $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); } } @@ -259,6 +239,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'); @@ -270,7 +251,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')); } } @@ -281,18 +262,18 @@ 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) { - $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']]); + $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) { $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); } } @@ -320,12 +301,13 @@ 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) { + $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; @@ -334,7 +316,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']; @@ -346,7 +328,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 02ed012b..47705ab2 100644 --- a/library/lib/tools.php +++ b/library/lib/tools.php @@ -286,33 +286,38 @@ 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 = []) +function simpleBulkSaveChangeHistory($table, $records, $changes, $now = null) { - // from and to variable must be arrays with entry 'int' or 'float' 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(), :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); } } 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.