PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.2.0
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.2.0
1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.2.0 All 28 releases
xspeed / includes / modules / Database / DatabaseModule.php

DatabaseModule.php in xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN 1.2.0, at includes/modules/Database/DatabaseModule.php

193 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Database cleanup module — read-first scan + selective cleanup +
4 * OPTIMIZE TABLE + optional auto-cleanup schedule.
5 *
6 * Tier: Free per FEATURES.md Database §1–11. (DB-side activity log
7 * Database §12 stays Pro.)
8 *
9 * @package XSpeed
10 */
11
12 declare(strict_types=1);
13
14 namespace XSpeed\Modules\Database;
15
16 defined( 'ABSPATH' ) || exit;
17
18 use XSpeed\Database_Cleaner;
19 use XSpeed\Module;
20 use XSpeed\Settings_Manager;
21
22 final class DatabaseModule extends Module {
23
24 public const SLUG = 'database';
25 public const TIER = self::TIER_FREE;
26 public const VERSION = '1.0.0';
27
28 public function ui_metadata(): array {
29 return array(
30 'label' => 'Database',
31 'icon' => 'Trash2',
32 'description' => 'Scan + clean WordPress bloat (revisions, spam, transients, orphan meta) and optimize tables.',
33 'custom_panel' => 'DatabaseCleanerPanel',
34 );
35 }
36
37 public function settings_schema(): array {
38 return array(
39 'schedule' => array(
40 'type' => 'enum',
41 'default' => 'manual',
42 'options' => array( 'manual', 'hourly', 'daily', 'weekly' ),
43 'option_labels' => array(
44 'manual' => 'Manual',
45 'hourly' => 'Hourly',
46 'daily' => 'Daily',
47 'weekly' => 'Weekly',
48 ),
49 'label' => 'Auto-Cleanup Schedule',
50 'description' => 'How often to run cleanup automatically. Manual means cleanup only runs when you press the button.',
51 ),
52 'included_types' => array(
53 'type' => 'list',
54 'default' => array(),
55 'item_type' => 'string',
56 'label' => 'Auto-Cleanup Types',
57 'description' => 'Which cleanup categories run on the schedule above. Leave empty to keep auto-cleanup disabled even if a schedule is set.',
58 ),
59 );
60 }
61
62 public function rest_routes(): array {
63 // Schema POST/GET come from the base; we add three custom routes.
64 $default = parent::rest_routes();
65 return array_merge(
66 $default,
67 array(
68 array(
69 'path' => '/scan',
70 'methods' => 'GET',
71 'callback' => array( $this, 'rest_scan' ),
72 ),
73 array(
74 'path' => '/clean',
75 'methods' => 'POST',
76 'callback' => array( $this, 'rest_clean' ),
77 ),
78 array(
79 'path' => '/optimize',
80 'methods' => 'POST',
81 'callback' => array( $this, 'rest_optimize' ),
82 ),
83 )
84 );
85 }
86
87 public function cli_commands(): array {
88 return array(
89 array(
90 'name' => 'xspeed db',
91 'callback' => array( $this, 'cli_handler' ),
92 'shortdesc' => 'Scan or clean WordPress bloat. Use --types=a,b to clean specific categories.',
93 'synopsis' => array(
94 array(
95 'type' => 'positional',
96 'name' => 'action',
97 'options' => array( 'scan', 'clean', 'optimize' ),
98 'optional' => false,
99 ),
100 array(
101 'type' => 'assoc',
102 'name' => 'types',
103 'optional' => true,
104 ),
105 ),
106 ),
107 );
108 }
109
110 public function boot(): void {
111 add_action( Database_Cleaner::CRON_HOOK, array( Database_Cleaner::class, 'cron_tick' ) );
112 add_action( 'update_option_xspeed_module_database', array( $this, 'on_settings_change' ), 10, 2 );
113 add_action( 'add_option_xspeed_module_database', array( $this, 'on_settings_added' ), 10, 2 );
114 }
115
116 public function deactivate(): void {
117 wp_clear_scheduled_hook( Database_Cleaner::CRON_HOOK );
118 }
119
120 public function on_settings_change( $old, $new ): void {
121 $schedule = is_array( $new ) ? (string) ( $new['schedule'] ?? 'manual' ) : 'manual';
122 $types = is_array( $new ) && isset( $new['included_types'] ) && is_array( $new['included_types'] ) ? $new['included_types'] : array();
123 Database_Cleaner::apply_schedule( $schedule, $types );
124 }
125
126 public function on_settings_added( $name, $value ): void {
127 $schedule = is_array( $value ) ? (string) ( $value['schedule'] ?? 'manual' ) : 'manual';
128 $types = is_array( $value ) && isset( $value['included_types'] ) && is_array( $value['included_types'] ) ? $value['included_types'] : array();
129 Database_Cleaner::apply_schedule( $schedule, $types );
130 }
131
132 public function rest_scan( \WP_REST_Request $request ) {
133 return rest_ensure_response(
134 array(
135 'scan' => Database_Cleaner::scan(),
136 'labels' => Database_Cleaner::type_labels(),
137 )
138 );
139 }
140
141 public function rest_clean( \WP_REST_Request $request ) {
142 $params = $request->get_json_params();
143 if ( ! is_array( $params ) ) {
144 $params = $request->get_params();
145 }
146 $types = isset( $params['types'] ) && is_array( $params['types'] ) ? $params['types'] : array();
147 if ( empty( $types ) ) {
148 return new \WP_Error( 'xspeed_db_no_types', __( 'Provide at least one cleanup type.', 'xspeed' ), array( 'status' => 400 ) );
149 }
150 return rest_ensure_response( Database_Cleaner::clean( $types ) );
151 }
152
153 public function rest_optimize( \WP_REST_Request $request ) {
154 return rest_ensure_response(
155 array(
156 'optimized' => Database_Cleaner::optimize_tables(),
157 )
158 );
159 }
160
161 public function cli_handler( array $args, array $assoc ): void {
162 $action = $args[0] ?? 'scan';
163
164 switch ( $action ) {
165 case 'scan':
166 foreach ( Database_Cleaner::scan() as $key => $row ) {
167 \WP_CLI::log( sprintf( '%-22s %s — %d rows', $key, $row['label'], $row['count'] ) );
168 }
169 return;
170
171 case 'clean':
172 $types = isset( $assoc['types'] ) ? array_filter( array_map( 'trim', explode( ',', (string) $assoc['types'] ) ) ) : array_keys( Database_Cleaner::type_labels() );
173 $res = Database_Cleaner::clean( $types );
174 foreach ( $res['cleaned'] as $key => $affected ) {
175 \WP_CLI::log( sprintf( '%-22s %d removed', $key, $affected ) );
176 }
177 \WP_CLI::success( 'Cleanup complete.' );
178 return;
179
180 case 'optimize':
181 $res = Database_Cleaner::optimize_tables();
182 foreach ( $res as $table => $ok ) {
183 \WP_CLI::log( sprintf( '%-40s %s', $table, $ok ? 'ok' : 'failed' ) );
184 }
185 \WP_CLI::success( 'Tables optimized.' );
186 return;
187
188 default:
189 \WP_CLI::error( "Unknown action: $action" );
190 }
191 }
192 }
193