connect with a pairing code from aoo (same as "เชื่อมกับ AOO") * wp aoo-shop menu-convert [--apply] [--undo] [--format=table|json] * menu items that point at WooCommerce → new shop links (dry run by default) * wp aoo-shop content-convert [--apply] [--ids=] [--undo] [--format=table|json|csv] * page content that uses WooCommerce → AooCommerce cards / links (dry run) * * @package AooShop */ defined( 'ABSPATH' ) || exit; class AooShop_Cli { public static function register() { if ( ! class_exists( 'WP_CLI' ) ) { return; } WP_CLI::add_command( 'aooshop status', array( __CLASS__, 'status' ) ); WP_CLI::add_command( 'aooshop connect', array( __CLASS__, 'connect' ) ); WP_CLI::add_command( 'aooshop menu-convert', array( __CLASS__, 'menu_convert' ) ); WP_CLI::add_command( 'aooshop content-convert', array( __CLASS__, 'content_convert' ) ); } /** * Show the connection and shop state. * * ## OPTIONS * * [--format=] * : table (default) or json. * * @param array $args Positional. * @param array $assoc Flags. */ public static function status( $args, $assoc ) { $p = aooshop(); $s = $p->settings; $remote = $s->remote(); $paths = $s->paths(); $rules = (array) get_option( 'rewrite_rules', array() ); $regex = '^' . preg_quote( ltrim( $paths['prefix_shop'], '/' ), '#' ) . '/([^/]+)/?$'; $stats = $p->cache->stats(); $rows = array( 'version' => AOOSHOP_VERSION, 'mode' => $s->mode() . ( $s->is_forced_preview() ? ' (forced: ' . implode( '; ', $s->collisions() ) . ')' : '' ), 'api_base' => $s->api_base(), 'key' => $s->is_configured() ? $s->masked_key() . ( $s->key_from_constant() ? ' (wp-config)' : '' ) : '(none)', 'last_ping' => empty( $remote['at'] ) ? 'never' : ( ! empty( $remote['ok'] ) ? 'ok' : 'FAILED: ' . ( isset( $remote['error'] ) ? $remote['error'] : '' ) ) . ' @ ' . wp_date( 'Y-m-d H:i', (int) $remote['at'] ), 'shop' => isset( $remote['company']['name'] ) ? (string) $remote['company']['name'] : '', 'connected_home' => $s->connected_home(), 'home_url' => home_url(), 'site_moved' => $s->moved_reason() ? $s->moved_message() : 'no', 'shop_url' => $p->router->url( 'index' ), 'rewrite_rules' => isset( $rules[ $regex ] ) ? 'ok' : 'missing (flushed on next request)', 'cache_pages' => (string) $stats['entries'] . ( $stats['api_down'] ? ' · AOO down (circuit)' : '' ), 'host_caches' => implode( ', ', $p->host_cache->detected() ), ); foreach ( $paths as $k => $v ) { $rows[ $k ] = $v; } if ( ! isset( $rules[ $regex ] ) ) { $p->router->request_flush(); } $items = array(); foreach ( $rows as $k => $v ) { $items[] = array( 'key' => $k, 'value' => (string) $v ); } WP_CLI\Utils\format_items( isset( $assoc['format'] ) ? $assoc['format'] : 'table', $items, array( 'key', 'value' ) ); } /** * Connect this site to AOO with a 6-character pairing code (AOO › ตั้งค่า › หน้าร้านออนไลน์ › WordPress). * * ## OPTIONS * * * : The pairing code (valid 10 minutes, single use). * * @param array $args Positional. * @param array $assoc Flags. */ public static function connect( $args, $assoc ) { $code = strtoupper( preg_replace( '/[^A-Za-z0-9]/', '', isset( $args[0] ) ? (string) $args[0] : '' ) ); if ( 6 !== strlen( $code ) ) { WP_CLI::error( __( 'The pairing code has 6 characters.', 'aoo-shop' ) ); } $res = aooshop()->api->pair( $code ); if ( is_wp_error( $res ) ) { WP_CLI::error( $res->get_error_message() ); } $ping = AooShop_Admin::after_connect( $res['key'] ); if ( is_wp_error( $ping ) ) { /* translators: %s: error message */ WP_CLI::warning( sprintf( __( 'Key stored, but the test ping failed: %s', 'aoo-shop' ), $ping->get_error_message() ) ); return; } $name = isset( $ping['company']['name'] ) ? (string) $ping['company']['name'] : ''; /* translators: 1: shop name 2: key label */ WP_CLI::success( sprintf( __( 'Connected to AOO — shop %1$s (%2$s)', 'aoo-shop' ), $name, $res['label'] ) ); } /** * Menu items that point at WooCommerce → links of the new shop. Dry run unless --apply. * Convert BEFORE switching WooCommerce off (taxonomy items need Woo to know their old URL). * * ## OPTIONS * * [--apply] * : Convert every item that has a new URL (original kept for undo). * * [--undo] * : Restore every item converted by this tool. * * [--format=] * : table (default), json, csv. * * @param array $args Positional. * @param array $assoc Flags. */ public static function menu_convert( $args, $assoc ) { $mc = aooshop()->menu_convert; $format = isset( $assoc['format'] ) ? $assoc['format'] : 'table'; if ( ! empty( $assoc['undo'] ) ) { $n = 0; foreach ( AooShop_Menu_Convert::converted_ids() as $id ) { $n += $mc->undo( $id ) ? 1 : 0; } /* translators: %d: number of menu items */ WP_CLI::success( sprintf( __( 'Restored %d menu item(s).', 'aoo-shop' ), $n ) ); return; } $plan = $mc->plan(); if ( ! $plan ) { WP_CLI::success( __( 'No menu item points at WooCommerce.', 'aoo-shop' ) ); return; } $apply = ! empty( $assoc['apply'] ); $done = 0; $rows = array(); foreach ( $plan as $r ) { $status = $r['converted'] ? 'converted' : ( '' === $r['new'] ? 'no match' : ( $apply ? 'converted now' : 'will convert' ) ); if ( $apply && ! $r['converted'] && '' !== $r['new'] ) { if ( $mc->convert( $r['id'], $r['new'] ) ) { $done++; } else { $status = 'failed'; } } $rows[] = array( 'id' => $r['id'], 'menu' => $r['menu'], 'title' => $r['title'], 'old' => rawurldecode( $r['old'] ), 'new' => rawurldecode( $r['new'] ), 'status' => $status, ); } WP_CLI\Utils\format_items( $format, $rows, array( 'id', 'menu', 'title', 'old', 'new', 'status' ) ); if ( $apply ) { /* translators: %d: number of menu items */ WP_CLI::success( sprintf( __( 'Converted %d menu item(s). Undo: wp aoo-shop menu-convert --undo', 'aoo-shop' ), $done ) ); } else { WP_CLI::log( __( 'Dry run — nothing changed. Run with --apply to convert.', 'aoo-shop' ) ); } } /** * Page content that uses WooCommerce (shortcodes, blocks, Elementor widgets, product links, Woo-only pages) * → AooCommerce equivalents. Dry run unless --apply. Works with WooCommerce on or off. * * ## OPTIONS * * [--apply] * : Convert every row that is ticked by default in the admin screen (content changes + the WooCommerce shop, * cart, checkout and account pages to trash). Originals are kept for undo. * * [--ids=] * : With --apply: only these post ids (comma separated) — also the ones not ticked by default (terms page, * Elementor WooCommerce templates). * * [--undo] * : Restore every post converted by this tool. * * [--format=] * : table (default), json, csv. * * @param array $args Positional. * @param array $assoc Flags. */ public static function content_convert( $args, $assoc ) { $cc = aooshop()->content_convert; $format = isset( $assoc['format'] ) ? $assoc['format'] : 'table'; if ( ! empty( $assoc['undo'] ) ) { $n = 0; foreach ( AooShop_Content_Convert::converted_ids() as $id ) { $n += $cc->undo( $id ) ? 1 : 0; } if ( $n ) { AooShop_Content_Convert::after_batch(); } /* translators: %d: number of posts */ WP_CLI::success( sprintf( __( 'Restored %d post(s).', 'aoo-shop' ), $n ) ); return; } $plan = $cc->plan(); if ( ! $plan ) { WP_CLI::success( __( 'No content uses WooCommerce.', 'aoo-shop' ) ); return; } $apply = ! empty( $assoc['apply'] ); $only = isset( $assoc['ids'] ) ? array_filter( array_map( 'absint', explode( ',', (string) $assoc['ids'] ) ) ) : array(); $done = 0; $rows = array(); foreach ( $plan as $r ) { $pick = $only ? in_array( $r['id'], $only, true ) : $r['checked']; $status = AooShop_Content_Convert::action_label( $r ); if ( $apply && $pick ) { $res = $cc->apply_row( $r ); if ( '' !== $res ) { $done++; $status = 'mismatch' === $res ? 'converted — Elementor read-back mismatch' : ( 'trashed' === $res ? 'trashed now' : 'converted now' ); } } elseif ( ! $pick && ( 'trash' === $r['action'] ? ! $r['trashed'] : ( null !== $r['content'] || null !== $r['elementor'] ) ) ) { $status .= ' (not selected — use --ids)'; } $rows[] = array( 'id' => $r['id'], 'type' => $r['type'] . '/' . $r['status'], 'title' => $r['title'], 'changes' => implode( ' | ', array_merge( AooShop_Content_Convert::fold_notes( $r['notes'] ), $r['review'] ) ), 'action' => $status, ); } WP_CLI\Utils\format_items( $format, $rows, array( 'id', 'type', 'title', 'changes', 'action' ) ); if ( $apply ) { if ( $done ) { AooShop_Content_Convert::after_batch(); } /* translators: %d: number of posts */ WP_CLI::success( sprintf( __( 'Changed %d post(s). Undo: wp aoo-shop content-convert --undo', 'aoo-shop' ), $done ) ); } else { WP_CLI::log( __( 'Dry run — nothing changed. Run with --apply to convert.', 'aoo-shop' ) ); } } }