PluginProbe
SQLite Object Cache / 1.5.1
SQLite Object Cache v1.5.1
1.6.5 trunk 0.1.7 1.0.0 1.1.0 1.1.1 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.4.0 1.4.1 1.5.1 1.5.4 1.5.5 1.5.6 1.5.7 All 30 releases
sqlite-object-cache / includes / cli.php

cli.php in SQLite Object Cache 1.5.1, at includes/cli.php

417 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /** @noinspection ALL */
2 /** @noinspection PhpUnused */
3 /** @noinspection PhpUndefinedFunctionInspection */
4 /** @noinspection PhpUndefinedNamespaceInspection */
5 /** @noinspection PhpUndefinedClassInspection */
6
7 /**
8 * SQLite Object Cache plugin
9 *
10 * ## OPTIONS
11 *
12 * [--format=<format>]
13 * : The display format. table, csv, json, yaml.
14 *
15 * [--blogid=<blogid>]
16 * : The blog id for a multisite network. --url also selects the blog if you prefer.
17 *
18 */
19 class SQLite_Object_Cache_CLI extends WP_CLI_Command {
20
21 public $db;
22 public $assoc_args;
23 public $cmd = 'wp index-mysql';
24 public $allSwitch = false;
25 public $rekeying;
26 public $errorMessages = [];
27 public $dryrun;
28 private $commentPrefix;
29
30 /**
31 * Show the version of the plugin.
32 *
33 */
34 function version( $args, $assoc_args ) {
35 $this->setupCliEnvironment( $args, $assoc_args );
36
37 global $wp_object_cache;
38 $igbinary = function_exists( 'igbinary_serialize' )
39 ? phpversion( 'igbinary' )
40 : __( 'unavailable', 'sqlite-object-cache' );
41 $force_serialize = defined( 'WP_SQLITE_OBJECT_CACHE_SERIALIZE' ) && WP_SQLITE_OBJECT_CACHE_SERIALIZE;
42 $igbinary .= $force_serialize ? esc_html__( '(disabled by WP_SQLITE_OBJECT_CACHE_SERIALIZE)', 'sqlite-object-cache' ) : '';
43
44 if ( method_exists( $wp_object_cache, 'sqlite_get_version' ) ) {
45 $msg = sprintf(
46 /* translators: 1: version for sqlite 2: version for plugin 3: igbinary --- for WP-CLI */
47 __( 'Versions: Plugin: %2$s SQLite: %1$s igbinary: %3$s.', 'sqlite-object-cache' ),
48 $wp_object_cache->sqlite_get_version(),
49 '1.5.1',
50 $igbinary );
51 }
52
53 WP_CLI::log( $this->commentPrefix . $msg );
54 }
55
56 /** @noinspection PhpUnusedParameterInspection */
57 private function setupCliEnvironment( $args, $assoc_args ) {
58 $this->assoc_args = $assoc_args;
59 if ( is_multisite() ) {
60 $restoreBlogId = get_current_blog_id();
61 if ( ! empty( $assoc_args['blogid'] ) ) {
62 $this->cmd .= ' --blogid=' . $assoc_args['blogid'];
63 switch_to_blog( $assoc_args['blogid'] );
64 } else {
65 switch_to_blog( $restoreBlogId );
66 }
67 }
68 }
69
70 /**
71 * Show status.
72 *
73 * @param $args
74 * @param $assoc_args
75 */
76 function status( $args, $assoc_args ) {
77 $this->setupCliEnvironment( $args, $assoc_args );
78 global $wp_object_cache;
79 if ( method_exists( $wp_object_cache, 'sqlite_sizes' ) ) {
80
81 $sizes = $wp_object_cache->sqlite_sizes();
82 $msgs = array();
83
84 /* translators: 1: size of .sqlite database file in MiB. --- for WP-CLI */
85 $msgs[] = sprintf( __( 'SQLite File Size Total: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $sizes['page_size'] * $sizes['total_pages'] / ( 1024.0 * 1024.0 ), 3 ) );
86 /* translators: 1: size of .sqlite database file free space in MiB. --- for WP-CLI */
87 $msgs[] = sprintf( __( 'Free: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $sizes['page_size'] * $sizes['free_pages'] / ( 1024.0 * 1024.0 ), 3 ) );
88 $mmapsize = $sizes['mmap_size'];
89 if ( $mmapsize > 0 ) {
90 /* translators: 1: size of memory mapped segment in MiB. --- for WP-CLI */
91 $msgs[] = sprintf( __( 'Memory Mapped Segment Size: %sMiB', 'sqlite-object-cache' ), number_format_i18n( $mmapsize / ( 1024.0 * 1024.0 ) ) );
92 }
93
94 $length = 0;
95 $count = 0;
96 $earliest = PHP_INT_MAX;
97 $latest = PHP_INT_MIN;
98 try {
99 foreach ( $wp_object_cache->sqlite_load_usages( true ) as $item ) {
100 $length += $item->length;
101 $count ++;
102 $ts = $item->expires;
103 $earliest = min( $earliest, $ts );
104 $latest = max( $latest, $ts );
105 }
106 } catch ( Exception $ex ) {
107 $length = 0;
108 $count = 0;
109 $earliest = PHP_INT_MAX;
110 $latest = PHP_INT_MIN;
111 }
112 if ( $length > 0 ) {
113 /* translators: 1: size of cached items in MiB. --- for WP-CLI */
114 $msgs[] = sprintf( __( 'Cached Data Size %sMiB', 'sqlite-object-cache' ), number_format_i18n( $length / ( 1024.0 * 1024.0 ), 3 ) );
115 }
116 if ( $count > 0 ) {
117 /* translators: 1: number of cached items. --- for WP-CLI */
118 $msgs[] = sprintf( __( 'Item Count: %s', 'sqlite-object-cache' ), number_format_i18n( $count ) );
119 }
120
121 if ( $earliest <= $latest ) {
122 /* translators: 1 start time 2 end time both in localized format. --- for WP-CLI */
123 $msgs[] = sprintf( __( 'Expirations: %1$s to %2$s.', 'sqlite-object-cache' ),
124 $this->format_datestamp( $earliest ), $this->format_datestamp( $latest ) );
125 }
126
127 WP_CLI::log( $this->commentPrefix . implode( ' ', $msgs ) );
128
129 }
130 }
131
132 /**
133 * Set or get the target size of the SQLite database file holding the object cache.
134 * ## OPTIONS
135 *
136 * [<size>]
137 * : The size to set in MiB. Omit to get the current size.
138 */
139 function size( $args, $assoc_args ) {
140
141 $targetAction = 1;
142 $this->setupCliEnvironment( $args, $assoc_args );
143 if ( count( $args ) > 1 ) {
144 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache size 64" sets it to 64MiB.', 'sqlite-object-cache' ) );
145 return;
146 }
147 list( $options, $old_target_size ) = $this->get_one_option( 'target_size' );
148
149 if ( 1 === count( $args ) ) {
150 $new_target_size = strval( $args[0] );
151 if ( $new_target_size === $old_target_size ) {
152 /* translators: 1: new target cache size --- for WP-CLI */
153 $msg = __( 'Target cache size unchanged at %1$sMiB', 'sqlite_object_cache' );
154 $msg = sprintf( $msg, $new_target_size );
155 WP_CLI::log( $this->commentPrefix . $msg );
156 } else {
157 /* translators: 1: new target cache size 2:former target cache size */
158 $msg = __( 'Target cache size changed from %2$sMiB to %1$sMiB', 'sqlite_object_cache' );
159 $msg = sprintf( $msg, $new_target_size, $old_target_size );
160 $options['target_size'] = strval( $new_target_size );
161 update_option( 'sqlite_object_cache_settings', $options, true );
162 WP_CLI::success( $this->commentPrefix . $msg );
163 }
164 } else {
165 /* translators: 1: target cache size */
166 $msg = __( 'Target cache size is %1$sMiB', 'sqlite_object_cache' );
167 $msg = sprintf( $msg, $old_target_size );
168 WP_CLI::log( $this->commentPrefix . $msg );
169 }
170
171 }
172
173 /**
174 * Set or get the performance measurement sample rate percentage. 0 disables measurement.
175 * ## OPTIONS
176 *
177 * [<samplerate>]
178 * : The sample rate to set. A number 0 - 100. Omit to get the current rate.
179 */
180 function samplerate( $args, $assoc_args ) {
181
182 $this->setupCliEnvironment( $args, $assoc_args );
183 if ( count( $args ) > 1 ) {
184 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache samplerate 10" samples ten percent.', 'sqlite-object-cache' ) );
185 return;
186 }
187 list( $options, $old_samplerate ) = $this->get_one_option( 'samplerate' );
188 list( $options, $old_capture ) = $this->get_one_option( 'capture' );
189 $old_samplerate = strval( ( $old_samplerate < 0 ) ? 0 : $old_samplerate );
190 $old_samplerate = strval( ( $old_samplerate > 100 ) ? 100 : $old_samplerate );
191 $old_capture = ( 'on' !== $old_capture ) ? 'off' : 'on';
192 $old_samplerate = strval( ( 'on' !== $old_capture ) ? 0 : $old_samplerate );
193 $old_capture = ( '0' === $old_samplerate ) ? 'off' : 'on';
194
195 if ( 1 === count( $args ) ) {
196 $new_samplerate = strval( $args[0] );
197 $new_samplerate = strval( ( $new_samplerate < 0 ) ? 0 : $new_samplerate );
198 $new_samplerate = strval( ( $new_samplerate > 100 ) ? 100 : $new_samplerate );
199 $new_capture = ( '0' === $new_samplerate ) ? 'off' : 'on';
200 if ( $old_samplerate === $new_samplerate ) {
201 /* translators: 1: new sample rate 0-100 --- for WP-CLI */
202 $msg = __( 'Performance measurement sample rate unchanged at %1$s%%', 'sqlite_object_cache' );
203 $msg = sprintf( $msg, $new_samplerate );
204 WP_CLI::log( $this->commentPrefix . $msg );
205 } else {
206 /* translators: 1: new rate 2:former rate --- for WP-CLI */
207 $msg = __( 'Performance measurement sample rate changed from %2$s%% to %1$s%%', 'sqlite_object_cache' );
208 $msg = sprintf( $msg, $new_samplerate, $old_samplerate );
209 $options['samplerate'] = strval( $new_samplerate );
210 $options['capture'] = $new_capture;
211
212 update_option( 'sqlite_object_cache_settings', $options, true );
213 WP_CLI::success( $this->commentPrefix . $msg );
214
215 }
216 } else {
217 /* translators: 1: sample rate --- for WP-CLI */
218 $msg = __( 'Performance measurement sample rate is %1$s%%', 'sqlite_object_cache' );
219 $msg = sprintf( $msg, $old_samplerate );
220 WP_CLI::log( $this->commentPrefix . $msg );
221 }
222
223 }
224
225 /**
226 * Set or get how long to retain performance measurements.
227 * ## OPTIONS
228 *
229 * [<time>]
230 * : The time in hours to retain measurements. Omit to get the current retention time.
231 */
232 function retain( $args, $assoc_args ) {
233
234 $this->setupCliEnvironment( $args, $assoc_args );
235 if ( count( $args ) > 1 ) {
236 WP_CLI::error( $this->commentPrefix . __( 'Too many args. "sqlite-object-cache retain 4" retains measuremewnts for 4 hours.', 'sqlite-object-cache' ) );
237 return;
238 }
239 list( $options, $old_samplerate ) = $this->get_one_option( 'retainmeasurements' );
240 $old_samplerate = strval( ( $old_samplerate < 1 ) ? 1 : $old_samplerate );
241
242 if ( 1 === count( $args ) ) {
243 $new_samplerate = strval( $args[0] );
244 $new_samplerate = strval( ( $new_samplerate < 1 ) ? 1 : $new_samplerate );
245 if ( $old_samplerate === $new_samplerate ) {
246 /* translators: 1: retention time --- for WP-CLI */
247 $msg = __( 'Performance measurement retention unchanged at %1$shr', 'sqlite_object_cache' );
248 $msg = sprintf( $msg, $new_samplerate );
249 WP_CLI::log( $this->commentPrefix . $msg );
250 } else {
251 /* translators: 1: new retention time 2:former time --- for WP-CLI */
252 $msg = __( 'Performance measurement retention changed from %2$shr to %1$shr', 'sqlite_object_cache' );
253 $msg = sprintf( $msg, $new_samplerate, $old_samplerate );
254 $options['retainmeasurements'] = strval( $new_samplerate );
255
256 update_option( 'sqlite_object_cache_settings', $options, true );
257 WP_CLI::success( $this->commentPrefix . $msg );
258
259 }
260 } else {
261 /* translators: 1: retention time --- for WP-CLI */
262 $msg = __( 'Performance measurement retention is %1$shr', 'sqlite_object_cache' );
263 $msg = sprintf( $msg, $old_samplerate );
264 WP_CLI::log( $this->commentPrefix . $msg );
265 }
266
267 }
268
269 /**
270 * Flush the cache (delete all its entries). This briefly puts your site into maintenance mode.
271 */
272 function flush( $args, $assoc_args ) {
273 global $wp_object_cache;
274 if ( method_exists( $wp_object_cache, 'flush' ) ) {
275 try {
276 $this->enter_maintenance_mode();
277 $wp_object_cache->flush( true );
278 } finally {
279 $this->exit_maintenance_mode();
280 }
281 }
282 }
283
284 /**
285 * Vacuum (defragment) the cache. This briefly puts your site into maintenance mode.
286 */
287 function vacuum( $args, $assoc_args ) {
288 global $wp_object_cache;
289 if ( method_exists( $wp_object_cache, 'vacuum' ) ) {
290 try {
291 $this->enter_maintenance_mode();
292 $wp_object_cache->vacuum();
293 } finally {
294 $this->exit_maintenance_mode();
295 }
296 }
297 }
298
299 /**
300 * Clean up (delete expired entries from) the cache.
301 */
302 function cleanup( $args, $assoc_args ) {
303 list( $options, $target_size ) = $this->get_one_option( 'target_size' );
304
305 $target_size *= ( 1024 * 1024 );
306 $threshold_size = (int) ( $target_size );
307
308 global $wp_object_cache;
309 if ( ! method_exists( $wp_object_cache, 'sqlite_get_size' ) ) {
310 return;
311 }
312
313 /* Always clean up old statistics. */
314 list( $options, $retention ) = $this->get_one_option( 'retainmeasurements' );
315 $wp_object_cache->sqlite_reset_statistics( $retention * HOUR_IN_SECONDS );
316
317 $original_size = $wp_object_cache->sqlite_get_size();
318 $current_size = $original_size;
319 /* Skip this if the current size is small enough. */
320 if ( $current_size <= $threshold_size ) {
321 /* translators: 1: size of cache --- For WP-CLI */
322 $msg = __( 'Cache contains %1$01.1fMiB, no cleanup performed', 'sqlite_object_cache' );
323 $msg = sprintf( $msg, $original_size / ( 1024.0 * 1024.0 ) );
324 WP_CLI::log( $this->commentPrefix . $msg );
325
326 return;
327 }
328
329 /* Remove expired items (transients mostly). */
330 if ( $wp_object_cache->sqlite_remove_expired() ) {
331 /* If anything was removed, get the size again. */
332 $current_size = $wp_object_cache->sqlite_get_size();
333
334 if ( $current_size < $original_size ) {
335 /* translators: 1: size removed 2: size remaining */
336 $msg = __( '%1$01.1fMiB of expired items removed from cache, leaving %2$01.1fMiB', 'sqlite_object_cache' );
337 $msg = sprintf( $msg, ( $original_size - $current_size ) / ( 1024.0 * 1024.0 ), ( $current_size ) / ( 1024.0 * 1024.0 ) );
338 WP_CLI::success( $this->commentPrefix . $msg );
339 }
340 }
341
342 /* Skip this if the size is small enough, after removing expired items. */
343 if ( $current_size <= $threshold_size ) {
344 return;
345 }
346
347 /* Delete the least-recently-updated items to get to the target size. */
348 $original_size = $current_size;
349 $wp_object_cache->sqlite_delete_old( $target_size, $current_size );
350 $current_size = $wp_object_cache->sqlite_get_size();
351 if ( $current_size < $original_size ) {
352 /* translators: 1: size removed 2: size remaining --- For WP-CLI */
353 $msg = __( '%1$01.1fMiB of least recently updated items removed from cache, leaving %2$01.1fMiB', 'sqlite_object_cache' );
354 $msg = sprintf( $msg, ( $original_size - $current_size ) / ( 1024.0 * 1024.0 ), ( $current_size ) / ( 1024.0 * 1024.0 ) );
355 WP_CLI::success( $this->commentPrefix . $msg );
356 }
357 }
358
359 private function get_one_option(
360 $name
361 ): array {
362 #a:5:{s:11:"target_size";s:2:"16";s:7:"capture";s:2:"on";s:10:"samplerate";s:3:"100";s:18:"retainmeasurements";s:1:"2";s:15:"previouscapture";i:0;}
363 $default = array(
364 'target_size' => '16',
365 'capture' => 'off',
366 'samplerate' => '1',
367 'retainmeasurements' => '2'
368 );
369 $options = get_option( 'sqlite_object_cache_settings', $default );
370 $val = strval( $options[ $name ] );
371 return array( $options, $val );
372 }
373
374 /**
375 * Enters maintenance mode.
376 *
377 * @return void
378 */
379 private function enter_maintenance_mode() {
380 $maintenanceFileName = ABSPATH . '.maintenance';
381 $maintain = array();
382 array_push( $maintain,
383 '<?php',
384 '$upgrading = ' . time() . ';',
385 '?>' );
386 file_put_contents( $maintenanceFileName, implode( PHP_EOL, $maintain ) );
387 }
388
389 /**
390 * Exits maintenance mode.
391 *
392 * @return void
393 */
394 private function exit_maintenance_mode() {
395 $maintenanceFileName = ABSPATH . '.maintenance';
396 unlink( $maintenanceFileName );
397 }
398
399 /**
400 * Format a UNIX timestamp using WP settings.
401 *
402 * @param $stamp
403 *
404 * @return false|string
405 */
406 private function format_datestamp(
407 $stamp
408 ) {
409 $date_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
410
411 return wp_date( $date_format, (int) $stamp );
412 }
413
414 }
415
416 WP_CLI::add_command( 'sqlite-object-cache', 'SQLite_Object_Cache_CLI' );
417