* : Product id. * * [--format=] * : table, json or csv. * --- * default: table * --- * * @param array $args Positional arguments. * @param array $assoc_args Options. */ public function list( $args, $assoc_args ): void { $id = absint( $args[0] ); $entries = Product_Tabs::get( $id ); $rows = array(); foreach ( $entries as $entry ) { $rows[] = array( 'type' => $entry['type'], 'key' => $entry['key'], 'title' => $entry['title'] ?? ( isset( $entry['library_id'] ) ? (string) get_the_title( (int) $entry['library_id'] ) : '' ), 'anchor' => $entry['anchor'] ?? '', 'library' => $entry['library_id'] ?? ( ! empty( $entry['origin'] ) ? 'from ' . $entry['origin'] : '' ), 'visible' => null === $entry['visible'] ? 'settings' : ( $entry['visible'] ? 'yes' : 'no' ), 'translated' => isset( $entry['translated'] ) ? ( $entry['translated'] ? 'yes' : 'no' ) : '', ); } \WP_CLI\Utils\format_items( $assoc_args['format'] ?? 'table', $rows, array( 'type', 'key', 'title', 'anchor', 'library', 'visible', 'translated' ) ); } /** * Imports the tabs of Custom Product Tabs for WooCommerce (YIKES). Its data is read, never changed. * * ## OPTIONS * * [--dry-run] * : Show what would be imported, write nothing. * * [--products[=]] * : Product ids separated by commas. All the products with YIKES tabs by default. * * [--overwrite] * : Import again the products that already have ProdTabs tabs (imported, or made by hand), and rewrite the shared * tabs already imported. The tabs they had before their first import are put back by --undo. * * [--the-content=] * : Format tab content with the full the_content filter. By default, as YIKES did on the first import, and * unchanged on the next ones. * * [--batch=] * : Products per batch. * --- * default: 50 * --- * * [--undo] * : Undo the import: the imported products get back the ProdTabs tabs they had before it (usually none), and the * shared tabs created by the import go to the trash, except those that other products use since. * * [--yes] * : Answer yes to the confirmation of --undo. * * ## EXAMPLES * * wp prodtabs import-yikes --dry-run * wp prodtabs import-yikes --products=14,15 * wp prodtabs import-yikes --undo * * @subcommand import-yikes * * @param array $args Positional arguments. * @param array $assoc_args Options. */ public function import_yikes( $args, $assoc_args ): void { // An empty list means every product: --products without any id (an empty variable, a SKU) stops here. $products = array(); if ( isset( $assoc_args['products'] ) ) { $products = true === $assoc_args['products'] ? array() : array_values( array_filter( array_map( 'absint', explode( ',', (string) $assoc_args['products'] ) ) ) ); if ( ! $products ) { \WP_CLI::error( 'No product id in --products: give ids separated by commas, or leave the option out to import every product.' ); } } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run', false ) ) { $this->dry_run( $products ); return; } if ( \WP_CLI\Utils\get_flag_value( $assoc_args, 'undo', false ) ) { \WP_CLI::confirm( 'Undo the import? The imported products get back the ProdTabs tabs they had before it, and the shared tabs created by the import go to the trash.', $assoc_args ); $undone = Import_Yikes::undo(); \WP_CLI::success( sprintf( 'Import undone: %d products cleaned (%d got their previous tabs back), %d shared tabs moved to the trash, %d kept because other products use them.', $undone['products'], $undone['restored'], $undone['library'], $undone['kept'] ) ); return; } // An explicit choice applies even after a first import; the default follows YIKES on the first import only. $given = isset( $assoc_args['the-content'] ); $state = Import_Yikes::start( array( 'products' => $products, 'overwrite' => (bool) \WP_CLI\Utils\get_flag_value( $assoc_args, 'overwrite', false ), 'the_content' => $given ? Tabs::to_bool( $assoc_args['the-content'] ) : Import_Yikes::used_the_content(), 'settings' => $given ? 'always' : 'first', ) ); $bar = \WP_CLI\Utils\make_progress_bar( 'Import', max( 1, (int) $state['total'] ) ); $done = 0; while ( 'running' === $state['status'] ) { $state = Import_Yikes::step( max( 1, (int) ( $assoc_args['batch'] ?? 50 ) ) ); $bar->tick( $state['done'] - $done ); $done = $state['done']; } $bar->finish(); $c = $state['counts']; \WP_CLI::log( sprintf( 'Products imported: %d, skipped: %d, without tabs: %d, errors: %d.', $c['imported'], $c['skipped'], $c['empty'], $c['errors'] ) ); \WP_CLI::log( sprintf( 'Tabs: %d, using a shared tab: %d, hidden: %d. Shared tabs created: %d.', $c['tabs'], $c['linked'], $c['hidden'], $c['library'] ) ); foreach ( $state['errors'] as $error ) { \WP_CLI::warning( sprintf( '%d: %s', $error[0], $error[1] ) ); } foreach ( $state['notes'] as $note ) { \WP_CLI::log( sprintf( 'Note %d %s %s', $note[0], $note[1], $note[2] ) ); } \WP_CLI::success( empty( $state['stopped'] ) ? 'Import finished.' : 'Import stopped from the import screen.' ); } /** * Prints the plan of an import. * * @param int[] $products Products, all when empty. */ private function dry_run( array $products ): void { $saved = Import_Yikes::read_saved(); $ids = $products ? array_values( array_intersect( Import_Yikes::product_ids(), $products ) ) : Import_Yikes::product_ids(); $plans = Import_Yikes::plans( $ids ); $rows = array(); foreach ( $ids as $id ) { $plan = $plans[ $id ]; $tabs = array(); foreach ( $plan['entries'] as $entry ) { if ( 'native' === $entry['type'] ) { if ( false === $entry['visible'] ) { $tabs[] = '-' . $entry['key']; } continue; } if ( 'library' === $entry['type'] ) { $label = 'shared:' . ( $saved[ $entry['library_id'] ]['title'] ?? $entry['library_id'] ); } elseif ( '' === $entry['title'] && '' === trim( $entry['content'] ) ) { $label = ( 'absent' === ( $entry['note'] ?? '' ) ? '(not in this language) ' : '(default language text) ' ) . $entry['key']; } else { $label = $entry['title'] . ( $entry['origin'] ? ' (customized)' : '' ); } $tabs[] = ( $entry['visible'] ? '' : '[hidden] ' ) . $label . ' #' . $entry['anchor']; } $rows[] = array( 'id' => $id, 'lang' => Multilingual::post_language( $id ), 'group' => $plan['group'], 'status' => $plan['status'], 'tabs' => implode( ' | ', $tabs ), 'notes' => implode( ', ', array_map( static fn( $n ) => $n[0], $plan['notes'] ) ), ); } \WP_CLI\Utils\format_items( 'table', $rows, array( 'id', 'lang', 'group', 'status', 'tabs', 'notes' ) ); \WP_CLI::log( sprintf( '%d products, %d saved tabs.', count( $ids ), count( $saved ) ) ); } }