PluginProbe
404 Solution / trunk
404 Solution vtrunk
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / admin / actions / TrashEmptier.php

TrashEmptier.php in 404 Solution trunk, at includes/admin/actions/TrashEmptier.php

87 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Permanently deletes disabled rows from the captured or redirect trash sets.
9 *
10 * This is data mutation infrastructure for the empty-trash admin handlers. It
11 * centralizes the status-set selection so the handlers never build SQL.
12 */
13 class ABJ_404_Solution_TrashEmptier {
14
15 /** @var ABJ_404_Solution_DatabaseQueryInterface */
16 private $dbCore;
17
18 /** @var ABJ_404_Solution_ViewReadServiceInterface */
19 private $viewRead;
20
21 /** @var ABJ_404_Solution_Logging */
22 private $logger;
23
24 /**
25 * @param ABJ_404_Solution_DatabaseQueryInterface $dbCore
26 * @param ABJ_404_Solution_ViewReadServiceInterface $viewRead
27 * @param ABJ_404_Solution_Logging $logger
28 */
29 public function __construct($dbCore, $viewRead, $logger) {
30 $this->dbCore = $dbCore;
31 $this->viewRead = $viewRead;
32 $this->logger = $logger;
33 }
34
35 /**
36 * @param string $sub Admin table slug: abj404_captured or abj404_redirects.
37 * @return void
38 */
39 public function emptyTrash(string $sub): void {
40 global $abj404_redirect_types;
41 global $abj404_captured_types;
42
43 if ($sub === 'abj404_captured') {
44 $statusTypes = is_array($abj404_captured_types) ? $abj404_captured_types : array();
45 } else if ($sub === 'abj404_redirects') {
46 $statusTypes = is_array($abj404_redirect_types) ? $abj404_redirect_types : array();
47 } else {
48 $this->logger->errorMessage("Unrecognized type in doEmptyTrash(" . $sub . ")");
49 return;
50 }
51
52 $statusList = array();
53 foreach ($statusTypes as $statusType) {
54 if (is_scalar($statusType)) {
55 $statusList[] = (string)$statusType;
56 }
57 }
58 if ($statusList === array()) {
59 $this->logger->errorMessage("No trash status types configured in doEmptyTrash(" . $sub . ")");
60 return;
61 }
62
63 $trashedRows = "disabled = 1 and status in (" . implode(", ", $statusList) . ")";
64
65 // Snapshot the rows about to be deleted so the Trash tab count drops
66 // to zero as soon as the page re-renders. Foreground count reads are
67 // cache-only (the aggregate is deferred to cron), so invalidating
68 // alone would leave the emptied Trash tab showing its old number.
69 $countsSync = new ABJ_404_Solution_StatusCountsMutationSync($this->dbCore);
70 $emptied = $countsSync->snapshot($trashedRows);
71
72 $query = "delete FROM {wp_abj404_redirects} \n" .
73 "where " . $trashedRows;
74
75 $result = $this->dbCore->queryAndGetResults($query);
76 $rowsAffected = is_array($result) && isset($result['rows_affected']) && is_scalar($result['rows_affected'])
77 ? (string)$result['rows_affected']
78 : '0';
79 $this->logger->debugMessage("doEmptyTrash deleted " . $rowsAffected . " rows total. (" . $sub . ")");
80
81 $this->viewRead->invalidateStatusCountsCache();
82 $countsSync->syncRemoved($emptied);
83
84 $this->dbCore->queryAndGetResults("optimize table {wp_abj404_redirects}");
85 }
86 }
87