265bd14903
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
154 lines
4.3 KiB
PHP
154 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* WP-CLI commands for spoke-sso AddOn.
|
|
*
|
|
* 從 wp-data-optimizer/cli/class-wpdo-cli-member.php 的 sso-sync / force-logout 抽出。
|
|
*
|
|
* @package TMDO_SPOKE
|
|
* @since 0.1.0
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
final class TMDO_Spoke_CLI {
|
|
|
|
/**
|
|
* 從舊 _tmso_* usermeta 同步到 wp_wpdo_user_sso flat table。
|
|
*
|
|
* ## OPTIONS
|
|
*
|
|
* [--user-id=<id>]
|
|
* : 限定單一 user 同步(預設全部)
|
|
*
|
|
* [--batch-size=<n>]
|
|
* : 每批處理筆數(預設 500)
|
|
*
|
|
* [--dry-run]
|
|
* : 只顯示會做什麼,不實際寫入
|
|
*
|
|
* @param array $args
|
|
* @param array $assoc_args
|
|
*/
|
|
public static function sync( $args, $assoc_args ): void {
|
|
$user_id = isset( $assoc_args['user-id'] ) ? absint( $assoc_args['user-id'] ) : 0;
|
|
$batch = isset( $assoc_args['batch-size'] ) ? max( 1, absint( $assoc_args['batch-size'] ) ) : 500;
|
|
$dry_run = ! empty( $assoc_args['dry-run'] );
|
|
|
|
if ( ! class_exists( 'TMDO_API' ) && ! class_exists( 'WPDO_API' ) ) {
|
|
\WP_CLI::error( '需要 2meet-data-optimizer 核心啟用' );
|
|
}
|
|
$api = class_exists( 'TMDO_API' ) ? 'TMDO_API' : 'WPDO_API';
|
|
|
|
global $wpdb;
|
|
$where = $user_id ? $wpdb->prepare( 'AND user_id = %d', $user_id ) : '';
|
|
// 支援 _tmso_global_user_id / _tmso_picture_url / _tmso_refresh_token 三個舊 key
|
|
$rows = $wpdb->get_results(
|
|
"SELECT user_id, meta_key, meta_value FROM {$wpdb->usermeta}
|
|
WHERE meta_key IN ('_tmso_global_user_id','_tmso_picture_url','_tmso_refresh_token')
|
|
$where
|
|
LIMIT $batch",
|
|
ARRAY_A
|
|
);
|
|
if ( empty( $rows ) ) {
|
|
\WP_CLI::success( '無待同步資料' );
|
|
return;
|
|
}
|
|
|
|
$migrated = 0;
|
|
$key_map = array(
|
|
'_tmso_global_user_id' => 'hub_global_user_id',
|
|
'_tmso_picture_url' => 'picture_url',
|
|
'_tmso_refresh_token' => 'refresh_token_enc',
|
|
);
|
|
|
|
foreach ( $rows as $row ) {
|
|
$dst_key = $key_map[ $row['meta_key'] ] ?? null;
|
|
if ( ! $dst_key ) {
|
|
continue;
|
|
}
|
|
if ( $dry_run ) {
|
|
\WP_CLI::log( "[dry-run] user={$row['user_id']} {$row['meta_key']} → {$dst_key}" );
|
|
} else {
|
|
$api::set_entity( 'user', (int) $row['user_id'], $dst_key, $row['meta_value'] );
|
|
}
|
|
$migrated++;
|
|
}
|
|
|
|
\WP_CLI::success( ( $dry_run ? '[dry-run] would migrate ' : 'migrated ' ) . $migrated . ' rows' );
|
|
}
|
|
|
|
/**
|
|
* 強制使用者 SSO token 過期(設 token_expires_at 為過去時間)。
|
|
*
|
|
* ## OPTIONS
|
|
*
|
|
* [--user-id=<id>]
|
|
* : Local user ID
|
|
*
|
|
* [--global-user-id=<uuid>]
|
|
* : Hub global user UUID
|
|
*
|
|
* [--all]
|
|
* : 強制全部 user 重認
|
|
*
|
|
* [--dry-run]
|
|
* : 只顯示會做什麼
|
|
*
|
|
* @param array $args
|
|
* @param array $assoc_args
|
|
*/
|
|
public static function force_logout( $args, $assoc_args ): void {
|
|
if ( ! class_exists( 'TMDO_API' ) && ! class_exists( 'WPDO_API' ) ) {
|
|
\WP_CLI::error( '需要 2meet-data-optimizer 核心啟用' );
|
|
}
|
|
$api = class_exists( 'TMDO_API' ) ? 'TMDO_API' : 'WPDO_API';
|
|
|
|
$dry_run = ! empty( $assoc_args['dry-run'] );
|
|
$user_id = isset( $assoc_args['user-id'] ) ? absint( $assoc_args['user-id'] ) : 0;
|
|
$global_uuid = isset( $assoc_args['global-user-id'] ) ? sanitize_text_field( $assoc_args['global-user-id'] ) : '';
|
|
$all = ! empty( $assoc_args['all'] );
|
|
|
|
if ( ! $user_id && ! $global_uuid && ! $all ) {
|
|
\WP_CLI::error( '需指定 --user-id / --global-user-id / --all 其中之一' );
|
|
}
|
|
|
|
global $wpdb;
|
|
$past = '2000-01-01 00:00:00';
|
|
$ids = array();
|
|
|
|
if ( $user_id ) {
|
|
$ids[] = $user_id;
|
|
} elseif ( $global_uuid ) {
|
|
$flat_table = $wpdb->prefix . 'wpdo_user_sso';
|
|
$id = $wpdb->get_var( $wpdb->prepare(
|
|
"SELECT user_id FROM $flat_table WHERE hub_global_user_id = %s LIMIT 1",
|
|
$global_uuid
|
|
) );
|
|
if ( $id ) {
|
|
$ids[] = (int) $id;
|
|
}
|
|
} elseif ( $all ) {
|
|
$flat_table = $wpdb->prefix . 'wpdo_user_sso';
|
|
$rows = $wpdb->get_col( "SELECT user_id FROM $flat_table" );
|
|
$ids = array_map( 'intval', $rows );
|
|
}
|
|
|
|
if ( empty( $ids ) ) {
|
|
\WP_CLI::warning( '找不到符合條件的 user' );
|
|
return;
|
|
}
|
|
|
|
foreach ( $ids as $uid ) {
|
|
if ( $dry_run ) {
|
|
\WP_CLI::log( "[dry-run] user={$uid} token_expires_at → {$past}" );
|
|
} else {
|
|
$api::set_entity( 'user', $uid, 'token_expires_at', $past );
|
|
}
|
|
}
|
|
|
|
\WP_CLI::success( ( $dry_run ? '[dry-run] would force-logout ' : 'force-logout ' ) . count( $ids ) . ' users' );
|
|
}
|
|
}
|