| @@ -54,15 +54,17 @@ | ||
| 54 | 54 | */ |
| 55 | 55 | public function archive_sites_changes( $before_timestamp = 0, $by_limit = 0, $dismiss = false ) { |
| 56 | 56 | $before_timestamp = 1000000 * $before_timestamp; |
| 57 | 57 | $where = ''; |
| 58 | - $order = ''; | |
| 58 | + $order_by = ''; | |
| 59 | + $batch_limit = 0; | |
| 59 | 60 | if ( ! empty( $before_timestamp ) ) { |
| 60 | 61 | $where .= ' AND created < ' . (int) $before_timestamp; |
| 61 | 62 | } |
| 62 | 63 | |
| 63 | 64 | if ( ! empty( $by_limit ) ) { |
| 64 | - $order .= ' ORDER BY created ASC LIMIT ' . (int) $by_limit; | |
| 65 | + $order_by .= ' created ASC '; | |
| 66 | + $batch_limit = (int) $by_limit; | |
| 65 | 67 | } |
| 66 | 68 | |
| 67 | 69 | if ( false !== $dismiss ) { |
| 68 | 70 | $where .= ' AND dismiss = ' . intval( $dismiss ); |
| @@ -67,9 +69,9 @@ | ||
| 67 | 69 | if ( false !== $dismiss ) { |
| 68 | 70 | $where .= ' AND dismiss = ' . intval( $dismiss ); |
| 69 | 71 | } |
| 70 | 72 | |
| 71 | - $this->bulk_archive_logs( $where, $order ); | |
| 73 | + $this->bulk_archive_logs( $where, $order_by, $batch_limit ); | |
| 72 | 74 | } |
| 73 | 75 | |
| 74 | 76 | |
| 75 | 77 | /** |
| @@ -75,14 +77,14 @@ | ||
| 75 | 77 | /** |
| 76 | 78 | * Bulk archive logs + meta with batching (no transaction). |
| 77 | 79 | * |
| 78 | 80 | * @param string $where SQL WHERE condition (MUST be prepared). |
| 79 | - * @param string $order SQL ORDER BY clause (e.g. "ORDER BY created ASC"). | |
| 80 | - * @param int $batch_size Number of rows per batch. | |
| 81 | + * @param string $order_by Column and direction for ORDER BY (e.g. "created ASC"). | |
| 82 | + * @param int $batch_limit Number of rows per batch. | |
| 81 | 83 | * |
| 82 | 84 | * @return int Total archived rows. |
| 83 | 85 | */ |
| 84 | - public function bulk_archive_logs( $where, $order, $batch_size = 1000 ) { | |
| 86 | + public function bulk_archive_logs( $where, $order_by, $batch_limit = 1000 ) { | |
| 85 | 87 | global $wpdb; |
| 86 | 88 | |
| 87 | 89 | $table_logs = $this->table_name( 'wp_logs' ); |
| 88 | 90 | $table_logs_archive = $this->table_name( 'wp_logs_archive' ); |
| @@ -92,13 +94,14 @@ | ||
| 92 | 94 | $total_archived = 0; |
| 93 | 95 | |
| 94 | 96 | do { |
| 95 | 97 | // 1. Get batch IDs. |
| 98 | + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- SQL fragments are built from integer-cast archive inputs; table name is internal. | |
| 96 | 99 | $ids = $this->wpdb->get_col( |
| 97 | 100 | "SELECT log_id |
| 98 | 101 | FROM $table_logs |
| 99 | - WHERE 1 $where $order | |
| 100 | - LIMIT " . intval( $batch_size ) | |
| 102 | + WHERE 1 $where " . ( ! empty( $order_by ) ? " ORDER BY $order_by " : '' ) . // phpcs:ignore -- NOSONAR -no user input | |
| 103 | + ( $batch_limit ? ' LIMIT ' . intval( $batch_limit ) : '' ) | |
| 101 | 104 | ); |
| 102 | 105 | |
| 103 | 106 | if ( empty( $ids ) ) { |
| 104 | 107 | break; |
| @@ -106,8 +109,9 @@ | ||
| 106 | 109 | |
| 107 | 110 | $ids_in = implode( ',', array_map( 'intval', $ids ) ); |
| 108 | 111 | |
| 109 | 112 | // 2. Archive logs (prevent duplicates). |
| 113 | + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table names are internal. | |
| 110 | 114 | $this->wpdb->query( |
| 111 | 115 | "INSERT IGNORE INTO $table_logs_archive |
| 112 | 116 | SELECT l.*, UNIX_TIMESTAMP() AS archived_at |
| 113 | 117 | FROM $table_logs l |
| @@ -114,8 +118,9 @@ | ||
| 114 | 118 | WHERE l.log_id IN ($ids_in)" |
| 115 | 119 | ); |
| 116 | 120 | |
| 117 | 121 | // 3. Archive meta (prevent duplicates). |
| 122 | + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table names are internal. | |
| 118 | 123 | $this->wpdb->query( |
| 119 | 124 | "INSERT IGNORE INTO $table_meta_archive |
| 120 | 125 | SELECT m.* |
| 121 | 126 | FROM $table_meta m |
| @@ -122,8 +127,9 @@ | ||
| 122 | 127 | WHERE m.meta_log_id IN ($ids_in)" |
| 123 | 128 | ); |
| 124 | 129 | |
| 125 | 130 | // 4. Delete meta first. |
| 131 | + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table name is internal. | |
| 126 | 132 | $this->wpdb->query( |
| 127 | 133 | "DELETE FROM $table_meta |
| 128 | 134 | WHERE meta_log_id IN ($ids_in)" |
| 129 | 135 | ); |
| @@ -128,8 +134,9 @@ | ||
| 128 | 134 | WHERE meta_log_id IN ($ids_in)" |
| 129 | 135 | ); |
| 130 | 136 | |
| 131 | 137 | // 5. Delete logs |
| 138 | + // phpcs:ignore PluginCheck.Security.DirectDB.UnescapedDBParameter -- $ids_in contains only intval() log IDs selected from the DB; table name is internal. | |
| 132 | 139 | $this->wpdb->query( |
| 133 | 140 | "DELETE FROM $table_logs |
| 134 | 141 | WHERE log_id IN ($ids_in)" |
| 135 | 142 | ); |
| @@ -135,9 +142,9 @@ | ||
| 135 | 142 | ); |
| 136 | 143 | |
| 137 | 144 | $total_archived += count( $ids ); |
| 138 | 145 | |
| 139 | - } while ( count( $ids ) === $batch_size ); | |
| 146 | + } while ( count( $ids ) === $batch_limit ); // Continue if we hit the batch limit. | |
| 140 | 147 | |
| 141 | 148 | return $total_archived; |
| 142 | 149 | } |
| 143 | 150 | |