PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.0.4
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.0.4
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.0.4, at includes/modules/Database/DatabaseModule.php

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