PluginProbe
Sessions / 2.3.1
Sessions v2.3.1
2.1.0 2.10.0 2.11.0 2.12.0 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.2.0 2.3.0 2.3.1 2.4.0 2.4.1 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.1.0 3.1.1 All 39 releases
sessions / includes / features / class-wpcli.php

class-wpcli.php in Sessions 2.3.1, at includes/features/class-wpcli.php

735 lines 21.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WP-CLI for Sessions.
4 *
5 * Adds WP-CLI commands to Sessions
6 *
7 * @package Features
8 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
9 * @since 1.0.0
10 */
11
12 namespace POSessions\Plugin\Feature;
13
14 use POSessions\System\Environment;
15
16 use POSessions\System\Option;
17 use POSessions\System\Markdown;
18 use POSessions\Plugin\Feature\Analytics;
19 use POSessions\Plugin\Feature\Schema;
20 use POSessions\System\Session;
21 use POSessions\System\Timezone;
22 use POSessions\System\GeoIP;
23 use POSessions\System\User;
24 use POSessions\System\IP;
25 use POSessions\System\UserAgent;
26 use POSessions\System\Date;
27 use POSessions\System\EmojiFlag;
28 use Spyc;
29
30 /**
31 * Manages users' sessions and get details about their use.
32 *
33 * @package Features
34 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
35 * @since 1.0.0
36 */
37 class Wpcli {
38
39 /**
40 * List of exit codes.
41 *
42 * @since 1.0.0
43 * @var array $exit_codes Exit codes.
44 */
45 private $exit_codes = [
46 0 => 'operation successful.',
47 1 => 'unrecognized setting.',
48 2 => 'unrecognized action.',
49 3 => 'analytics are disabled.',
50 4 => 'unrecognized mode.',
51 5 => 'user doesn\'t exist.',
52 255 => 'unknown error.',
53 ];
54
55 /**
56 * Write ids as clean stdout.
57 *
58 * @param array $ids The ids.
59 * @param string $field Optional. The field to output.
60 * @since 1.0.0
61 */
62 private function write_ids( $ids, $field = '' ) {
63 $result = '';
64 $last = end( $ids );
65 foreach ( $ids as $key => $id ) {
66 if ( '' === $field ) {
67 $result .= $key;
68 } else {
69 $result .= $id[$field];
70 }
71 if ( $id !== $last ) {
72 $result .= ' ';
73 }
74 }
75 // phpcs:ignore
76 fwrite( STDOUT, $result );
77 }
78
79 /**
80 * Write an error.
81 *
82 * @param integer $code Optional. The error code.
83 * @param boolean $stdout Optional. Clean stdout output.
84 * @since 1.0.0
85 */
86 private function error( $code = 255, $stdout = false ) {
87 if ( \WP_CLI\Utils\isPiped() ) {
88 // phpcs:ignore
89 fwrite( STDOUT, '' );
90 // phpcs:ignore
91 exit( $code );
92 } elseif ( $stdout ) {
93 // phpcs:ignore
94 fwrite( STDERR, ucfirst( $this->exit_codes[ $code ] ) );
95 // phpcs:ignore
96 exit( $code );
97 } else {
98 \WP_CLI::error( $this->exit_codes[ $code ] );
99 }
100 }
101
102 /**
103 * Write an error from a WP_Error object.
104 *
105 * @param \WP_Error $err The error object.
106 * @param boolean $stdout Optional. Clean stdout output.
107 * @since 1.0.0
108 */
109 private function error_from_object( $err, $stdout = false ) {
110 $msg = $this->exit_codes[255];
111 if ( is_wp_error( $err ) ) {
112 $msg = $err->get_error_message();
113 }
114 if ( \WP_CLI\Utils\isPiped() ) {
115 // phpcs:ignore
116 fwrite( STDOUT, '' );
117 // phpcs:ignore
118 exit( 255 );
119 } elseif ( $stdout ) {
120 // phpcs:ignore
121 fwrite( STDERR, ucfirst( $msg ) );
122 // phpcs:ignore
123 exit( 255 );
124 } else {
125 \WP_CLI::error( $msg );
126 }
127 }
128
129 /**
130 * Write a warning.
131 *
132 * @param string $msg The message.
133 * @param string $result Optional. The result.
134 * @param boolean $stdout Optional. Clean stdout output.
135 * @since 1.0.0
136 */
137 private function warning( $msg, $result = '', $stdout = false ) {
138 if ( \WP_CLI\Utils\isPiped() || $stdout ) {
139 // phpcs:ignore
140 fwrite( STDOUT, $result );
141 } else {
142 \WP_CLI::warning( $msg );
143 }
144 }
145
146 /**
147 * Write a success.
148 *
149 * @param string $msg The message.
150 * @param string $result Optional. The result.
151 * @param boolean $stdout Optional. Clean stdout output.
152 * @since 1.0.0
153 */
154 private function success( $msg, $result = '', $stdout = false ) {
155 if ( \WP_CLI\Utils\isPiped() || $stdout ) {
156 // phpcs:ignore
157 fwrite( STDOUT, $result );
158 } else {
159 \WP_CLI::success( $msg );
160 }
161 }
162
163 /**
164 * Write a wimple line.
165 *
166 * @param string $msg The message.
167 * @param string $result Optional. The result.
168 * @param boolean $stdout Optional. Clean stdout output.
169 * @since 1.0.0
170 */
171 private function line( $msg, $result = '', $stdout = false ) {
172 if ( \WP_CLI\Utils\isPiped() || $stdout ) {
173 // phpcs:ignore
174 fwrite( STDOUT, $result );
175 } else {
176 \WP_CLI::line( $msg );
177 }
178 }
179
180 /**
181 * Write a wimple log line.
182 *
183 * @param string $msg The message.
184 * @param boolean $stdout Optional. Clean stdout output.
185 * @since 1.0.0
186 */
187 private function log( $msg, $stdout = false ) {
188 if ( ! \WP_CLI\Utils\isPiped() && ! $stdout ) {
189 \WP_CLI::log( $msg );
190 }
191 }
192
193 /**
194 * Get params from command line.
195 *
196 * @param array $args The command line parameters.
197 * @return array The true parameters.
198 * @since 1.0.0
199 */
200 private function get_params( $args ) {
201 $result = '';
202 if ( array_key_exists( 'settings', $args ) ) {
203 $result = \json_decode( $args['settings'], true );
204 }
205 if ( ! $result || ! is_array( $result ) ) {
206 $result = [];
207 }
208 return $result;
209 }
210
211 /**
212 * Get Sessions details and operation modes.
213 *
214 * ## EXAMPLES
215 *
216 * wp sessions status
217 *
218 *
219 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
220 *
221 */
222 public function status( $args, $assoc_args ) {
223 \WP_CLI::line( sprintf( '%s is running.', Environment::plugin_version_text() ) );
224 switch ( Option::network_get( 'rolemode' ) ) {
225 case -1:
226 \WP_CLI::line( 'Operation mode: no role limitation.' );
227 break;
228 case 0:
229 \WP_CLI::line( 'Operation mode: role limitation with cumulative privileges.' );
230 break;
231 case 1:
232 \WP_CLI::line( 'Operation mode: role limitation with least privileges.' );
233 break;
234
235 }
236 if ( Option::network_get( 'forceip' ) ) {
237 \WP_CLI::line( 'IP override: enabled.' );
238 } else {
239 \WP_CLI::line( 'IP override: disabled.' );
240 }
241 if ( Option::network_get( 'followip' ) ) {
242 \WP_CLI::line( 'IP follow-up: enabled.' );
243 } else {
244 \WP_CLI::line( 'IP follow-up: disabled.' );
245 }
246 if ( Option::network_get( 'analytics' ) ) {
247 \WP_CLI::line( 'Analytics: enabled.' );
248 } else {
249 \WP_CLI::line( 'Analytics: disabled.' );
250 }
251 if ( Option::network_get( 'metrics' ) ) {
252 \WP_CLI::line( 'Metrics collation: enabled.' );
253 } else {
254 \WP_CLI::line( 'Metrics collation: disabled.' );
255 }
256 if ( \DecaLog\Engine::isDecalogActivated() ) {
257 \WP_CLI::line( 'Logging support: ' . \DecaLog\Engine::getVersionString() . '.');
258 } else {
259 \WP_CLI::line( 'Logging support: no.' );
260 }
261 $geo = new GeoIP();
262 if ( $geo->is_installed() ) {
263 \WP_CLI::line( 'IP information support: yes (' . $geo->get_full_name() . ').');
264 } else {
265 \WP_CLI::line( 'IP information support: no.' );
266 }
267 if ( defined( 'PODD_VERSION' ) ) {
268 \WP_CLI::line( 'Device detection support: yes (Device Detector v' . PODD_VERSION . ').');
269 } else {
270 \WP_CLI::line( 'Device detection support: no.' );
271 }
272 }
273
274 /**
275 * Modify Sessions main settings.
276 *
277 * ## OPTIONS
278 *
279 * <enable|disable>
280 * : The action to take.
281 *
282 * <analytics|ip-override|ip-follow|metrics>
283 * : The setting to change.
284 *
285 * [--yes]
286 * : Answer yes to the confirmation message, if any.
287 *
288 * [--stdout]
289 * : Use clean STDOUT output to use results in scripts. Unnecessary when piping commands because piping is detected by Sessions.
290 *
291 * ## EXAMPLES
292 *
293 * wp sessions settings disable analytics --yes
294 *
295 *
296 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
297 *
298 */
299 public function settings( $args, $assoc_args ) {
300 $stdout = \WP_CLI\Utils\get_flag_value( $assoc_args, 'stdout', false );
301 $action = isset( $args[0] ) ? (string) $args[0] : '';
302 $setting = isset( $args[1] ) ? (string) $args[1] : '';
303 switch ( $action ) {
304 case 'enable':
305 switch ( $setting ) {
306 case 'analytics':
307 Option::network_set( 'analytics', true );
308 $this->success( 'analytics are now activated.', '', $stdout );
309 break;
310 case 'ip-follow':
311 Option::network_set( 'followip', true );
312 $this->success( 'IP follow-up is now activated.', '', $stdout );
313 break;
314 case 'ip-override':
315 Option::network_set( 'forceip', true );
316 $this->success( 'IP override is now activated.', '', $stdout );
317 break;
318 case 'metrics':
319 Option::network_set( 'metrics', true );
320 $this->success( 'metrics collation is now activated.', '', $stdout );
321 break;
322 default:
323 $this->error( 1, $stdout );
324 }
325 break;
326 case 'disable':
327 switch ( $setting ) {
328 case 'analytics':
329 \WP_CLI::confirm( 'Are you sure you want to deactivate analytics?', $assoc_args );
330 Option::network_set( 'analytics', false );
331 $this->success( 'analytics are now deactivated.', '', $stdout );
332 break;
333 case 'ip-follow':
334 \WP_CLI::confirm( 'Are you sure you want to deactivate IP follow-up?', $assoc_args );
335 Option::network_set( 'followip', false );
336 $this->success( 'IP follow-up is now deactivated.', '', $stdout );
337 break;
338 case 'ip-override':
339 \WP_CLI::confirm( 'Are you sure you want to deactivate IP override?', $assoc_args );
340 Option::network_set( 'forceip', false );
341 $this->success( 'IP override is now deactivated.', '', $stdout );
342 break;
343 case 'metrics':
344 \WP_CLI::confirm( 'Are you sure you want to deactivate metrics collation?', $assoc_args );
345 Option::network_set( 'metrics', false );
346 $this->success( 'metrics collation is now deactivated.', '', $stdout );
347 break;
348 default:
349 $this->error( 1, $stdout );
350 }
351 break;
352 default:
353 $this->error( 2, $stdout );
354 }
355 }
356
357 /**
358 * Modify Sessions operation mode.
359 *
360 * ## OPTIONS
361 *
362 * <set>
363 * : The action to take.
364 *
365 * <none|cumulative|least>
366 * : The mode to set.
367 *
368 * [--yes]
369 * : Answer yes to the confirmation message, if any.
370 *
371 * [--stdout]
372 * : Use clean STDOUT output to use results in scripts. Unnecessary when piping commands because piping is detected by Sessions.
373 *
374 * ## EXAMPLES
375 *
376 * wp sessions mode set none --yes
377 *
378 *
379 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
380 *
381 */
382 public function mode( $args, $assoc_args ) {
383 $stdout = \WP_CLI\Utils\get_flag_value( $assoc_args, 'stdout', false );
384 $action = isset( $args[0] ) ? (string) $args[0] : '';
385 $mode = isset( $args[1] ) ? (string) $args[1] : '';
386 switch ( $action ) {
387 case 'set':
388 switch ( $mode ) {
389 case 'none':
390 \WP_CLI::confirm( 'Are you sure you want to deactivate role-mode?', $assoc_args );
391 Option::network_set( 'rolemode', -1 );
392 $this->success( 'operation mode is now "no role limitation".', '', $stdout );
393 break;
394 case 'cumulative':
395 Option::network_set( 'rolemode', 0 );
396 $this->success( 'operation mode is now "role limitation with cumulative privileges".', '', $stdout );
397 break;
398 case 'least':
399 Option::network_set( 'rolemode', 1 );
400 $this->success( 'operation mode is now "role limitation with least privileges".', '', $stdout );
401 break;
402 default:
403 $this->error( 4, $stdout );
404 break;
405 }
406 break;
407 default:
408 $this->error( 2, $stdout );
409 }
410 }
411
412 /**
413 * Get sessions analytics for today.
414 *
415 * ## OPTIONS
416 *
417 * [--site=<site_id>]
418 * : The site for which to display analytics. May be 0 (all network) or an integer site id. Only useful with multisite environments.
419 * ---
420 * default: 0
421 * ---
422 *
423 * [--format=<format>]
424 * : Set the output format. Note if json is chosen: full metadata is outputted too.
425 * ---
426 * default: table
427 * options:
428 * - table
429 * - json
430 * - csv
431 * - yaml
432 * - count
433 * ---
434 *
435 * [--stdout]
436 * : Use clean STDOUT output to use results in scripts. Unnecessary when piping commands because piping is detected by Sessions.
437 *
438 * ## EXAMPLES
439 *
440 * wp sessions analytics
441 *
442 *
443 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
444 *
445 */
446 public function analytics( $args, $assoc_args ) {
447 $stdout = \WP_CLI\Utils\get_flag_value( $assoc_args, 'stdout', false );
448 $site = (int) \WP_CLI\Utils\get_flag_value( $assoc_args, 'site', 0 );
449 $format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'table' );
450 if ( ! Option::network_get( 'analytics' ) ) {
451 $this->error( 3, $stdout );
452 }
453 $analytics = Analytics::get_status_kpi_collection( [ 'site_id' => $site ] );
454 $result = [];
455 if ( array_key_exists( 'data', $analytics ) ) {
456 foreach ( $analytics['data'] as $kpi ) {
457 $item = [];
458 $item['kpi'] = $kpi['name'];
459 $item['description'] = $kpi['description'];
460 $item['value'] = $kpi['value']['human'];
461 if ( array_key_exists( 'ratio', $kpi ) && isset( $kpi['ratio'] ) ) {
462 $item['ratio'] = $kpi['ratio']['percent'] . '%';
463 } else {
464 $item['ratio'] = '-';
465 }
466 $item['variation'] = ( 0 < $kpi['variation']['percent'] ? '+' : '' ) . (string) $kpi['variation']['percent'] . '%';
467 $result[] = $item;
468 }
469 }
470 if ( 'json' === $format ) {
471 $detail = wp_json_encode( $analytics );
472 $this->line( $detail, $detail, $stdout );
473 } elseif ( 'yaml' === $format ) {
474 unset( $analytics['assets'] );
475 $detail = Spyc::YAMLDump( $analytics, true, true, true );
476 $this->line( $detail, $detail, $stdout );
477 } else {
478 \WP_CLI\Utils\format_items( $assoc_args['format'], $result, [ 'kpi', 'description', 'value', 'ratio', 'variation' ] );
479 }
480 }
481
482 /**
483 * Get information on exit codes.
484 *
485 * ## OPTIONS
486 *
487 * <list>
488 * : The action to take.
489 * ---
490 * options:
491 * - list
492 * ---
493 *
494 * [--format=<format>]
495 * : Allows overriding the output of the command when listing exit codes.
496 * ---
497 * default: table
498 * options:
499 * - table
500 * - json
501 * - csv
502 * - yaml
503 * - ids
504 * - count
505 * ---
506 *
507 * ## EXAMPLES
508 *
509 * Lists available exit codes:
510 * + wp sessions exitcode list
511 * + wp sessions exitcode list --format=json
512 *
513 *
514 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
515 *
516 */
517 public function exitcode( $args, $assoc_args ) {
518 $stdout = \WP_CLI\Utils\get_flag_value( $assoc_args, 'stdout', false );
519 $format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'table' );
520 $action = isset( $args[0] ) ? $args[0] : 'list';
521 $codes = [];
522 foreach ( $this->exit_codes as $key => $msg ) {
523 $codes[ $key ] = [ 'code' => $key, 'meaning' => ucfirst( $msg ) ];
524 }
525 switch ( $action ) {
526 case 'list':
527 if ( 'ids' === $format ) {
528 $this->write_ids( $codes );
529 } else {
530 \WP_CLI\Utils\format_items( $format, $codes, [ 'code', 'meaning' ] );
531 }
532 break;
533 }
534 }
535
536 /**
537 * Get the WP-CLI help file.
538 *
539 * @param array $attributes 'style' => 'markdown', 'html'.
540 * 'mode' => 'raw', 'clean'.
541 * @return string The output of the shortcode, ready to print.
542 * @since 1.0.0
543 */
544 public static function sc_get_helpfile( $attributes ) {
545 $md = new Markdown();
546 return $md->get_shortcode( 'WP-CLI.md', $attributes );
547 }
548
549 /**
550 * Manage active sessions.
551 *
552 * ## OPTIONS
553 *
554 * <list|kill>
555 * : The action to take.
556 * ---
557 * options:
558 * - list
559 * - kill
560 * ---
561 *
562 * [<user_id>]
563 * : The id of the user to perform an action/search on. If nothing is specified, it's on all users.
564 *
565 * [--detail=<detail>]
566 * : The details of the output when listing application passwords.
567 * ---
568 * default: short
569 * options:
570 * - short
571 * - full
572 * ---
573 *
574 * [--format=<format>]
575 * : Allows overriding the output of the command when listing application passwords. Note if json or yaml is chosen: full metadata is outputted too.
576 * ---
577 * default: table
578 * options:
579 * - table
580 * - json
581 * - csv
582 * - yaml
583 * - ids
584 * - count
585 * ---
586 *
587 * [--yes]
588 * : Answer yes to the confirmation message, if any.
589 *
590 * [--stdout]
591 * : Use clean STDOUT output to use results in scripts. Unnecessary when piping commands because piping is detected by Sessions.
592 *
593 * ## EXAMPLES
594 *
595 * List active sessions:
596 * + wp sessions active list
597 * + wp sessions active list 1
598 *
599 * Kill active sessions:
600 * + wp sessions active kill
601 * + wp sessions active kill 1 --yes
602 *
603 *
604 * === For other examples and recipes, visit https://github.com/Pierre-Lannoy/wp-sessions/blob/master/WP-CLI.md ===
605 *
606 */
607 public function active( $args, $assoc_args ) {
608 $stdout = \WP_CLI\Utils\get_flag_value( $assoc_args, 'stdout', false );
609 $format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format', 'table' );
610 $detail = \WP_CLI\Utils\get_flag_value( $assoc_args, 'detail', 'short' );
611 $id = '';
612 $action = isset( $args[0] ) ? $args[0] : 'list';
613 if ( isset( $args[1] ) ) {
614 $id = (int) $args[1];
615 if ( false === get_userdata( $id ) ) {
616 $this->error( 5, $stdout );
617 }
618 }
619 switch ( $action ) {
620 case 'list':
621 $sessions = [];
622 $list = [];
623 $tz = Timezone::network_get();
624 if ( '' !== $id ) {
625 $list[] = [
626 'user_id' => $id,
627 'meta_value' => Session::get_user_sessions( $id ),
628 ];
629 } else {
630 $list = Session::get_all_sessions();
631 }
632 foreach ( $list as $user ) {
633 if ( array_key_exists( 'meta_value', $user ) && is_array( $user['meta_value'] ) ) {
634 foreach ( $user['meta_value'] as $token => $session ) {
635 $sessions[ $token ]['token'] = $token;
636 $sessions[ $token ]['user-id'] = (int) $user['user_id'];
637 $sessions[ $token ]['user'] = User::get_user_string( $user['user_id'] );
638 if ( array_key_exists( 'expiration', $session ) ) {
639 $datetime = new \DateTime( date( 'Y-m-d H:i:s', $session['expiration'] ) );
640 $datetime->setTimezone( $tz );
641 $sessions[ $token ]['standard exp'] = $datetime->format( 'Y-m-d H:i' );
642 } else {
643 $sessions[ $token ]['standard exp'] = 'never';
644 }
645 if ( array_key_exists( 'login', $session ) ) {
646 $datetime = new \DateTime( date( 'Y-m-d H:i:s', $session['login'] ) );
647 $datetime->setTimezone( $tz );
648 $sessions[ $token ]['login'] = $datetime->format( 'Y-m-d H:i' );
649 } else {
650 $sessions[ $token ]['login'] = 'never';
651 }
652 if ( array_key_exists( 'session_idle', $session ) ) {
653 $value = $session['session_idle'] - time();
654 if ( 0 === $value ) {
655 $sessions[ $token ]['idle exp'] = 'now';
656 } else {
657 $value = 0 - $value;
658 if ( $value < 72 * HOUR_IN_SECONDS ) {
659 $sessions[ $token ]['idle exp'] = implode( ', ', Date::get_age_array_from_seconds( $value, true, true ) );
660 } else {
661 $sessions[ $token ]['idle exp'] = (int) round( $value / ( 24 * HOUR_IN_SECONDS ), 0 ) . 'days';
662 }
663 }
664 } else {
665 $sessions[ $token ]['idle exp'] = '-';
666 }
667 $sessions[ $token ]['ip'] = $session['ip'];
668 if ( 'full' === $detail ) {
669 $sessions[ $token ]['device'] = '-';
670 $sessions[ $token ]['os'] = '-';
671 $sessions[ $token ]['client'] = '-';
672 if ( array_key_exists( 'ua', $session ) ) {
673 $device = UserAgent::get( $session['ua'] );
674 $sessions[ $token ]['device'] = ( '' !== $device->brand_name ? $device->brand_name : esc_html__( 'Generic', 'sessions' ) ) . ( '' !== $device->model_name ? ' ' . $device->model_name : '' );
675 $sessions[ $token ]['os'] = $device->os_name . ( '' !== $device->os_version ? ' ' . $device->os_version : '' );
676 $sessions[ $token ]['client'] = ( '' !== $device->client_name ? $device->client_name : $device->client_full_type );
677 if ( $device->client_is_browser ) {
678 $sessions[ $token ]['client'] = $device->client_name . ( '' !== $device->client_version ? ' ' . $device->client_version : '' );
679 }
680 }
681 }
682 }
683 }
684 }
685 usort(
686 $sessions,
687 function ( $a, $b ) {
688 return strcmp( strtolower( $a[ 'user' ] ), strtolower( $b[ 'user' ] ) );
689 }
690 );
691 if ( 'full' === $detail ) {
692 $detail = [ 'user', 'ip', 'device', 'os', 'client', 'login', 'idle exp', 'standard exp' ];
693 } else {
694 $detail = [ 'user', 'ip', 'login', 'idle exp', 'standard exp' ];
695 }
696 if ( 'ids' === $format ) {
697 $this->write_ids( $sessions, 'uuid' );
698 } elseif ( 'yaml' === $format ) {
699 $details = Spyc::YAMLDump( $sessions, true, true, true );
700 $this->line( $details, $details, $stdout );
701 } elseif ( 'json' === $format ) {
702 $details = wp_json_encode( $sessions );
703 $this->line( $details, $details, $stdout );
704 } else {
705 \WP_CLI\Utils\format_items( $format, $sessions, $detail );
706 }
707 break;
708 case 'kill':
709 if ( '' === $id ) {
710 \WP_CLI::confirm( 'Are you sure you want to kill all sessions for all users?', $assoc_args );
711 $cnt = Session::delete_all_sessions();
712 } else {
713 \WP_CLI::confirm( 'Are you sure you want to kill all sessions for this user?', $assoc_args );
714 $cnt = Session::delete_all_sessions( $id );
715 }
716 if ( false === $cnt ) {
717 $this->error( 255, $stdout );
718 } else {
719 if ( 0 === (int) $cnt ) {
720 $this->success( 'no session to kill.', 0, $stdout );
721 } else {
722 $this->success( $cnt . ' session(s) killed.', $cnt, $stdout );
723 }
724 }
725 break;
726 }
727 }
728
729 }
730
731 add_shortcode( 'pose-wpcli', [ 'POSessions\Plugin\Feature\Wpcli', 'sc_get_helpfile' ] );
732
733 if ( defined( 'WP_CLI' ) && WP_CLI ) {
734 \WP_CLI::add_command( 'sessions', 'POSessions\Plugin\Feature\Wpcli' );
735 }