$spec ) { $report = AIEO_Content_Compiler::apply( $spec, array( 'mode' => (string) ( $assoc['mode'] ?? 'draft' ), 'status' => (string) ( $assoc['status'] ?? '' ), 'force' => $force, 'dry_run' => ! empty( $assoc['dry-run'] ), ) + self::media_opts( $assoc, $file ) ); if ( is_wp_error( $report ) ) { ++$failed; WP_CLI::warning( sprintf( '%s: %s', basename( $file ), $report->get_error_message() ) ); continue; } $reports[] = $report; self::print_report( $report, (string) ( $assoc['format'] ?? 'table' ) ); } if ( 'json' === (string) ( $assoc['format'] ?? '' ) ) { WP_CLI::line( (string) wp_json_encode( $reports, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ); } if ( $failed ) { WP_CLI::error( sprintf( '%d spec(s) failed.', $failed ) ); } WP_CLI::success( sprintf( '%d page(s) %s.', count( $reports ), ! empty( $assoc['dry-run'] ) ? 'planned' : ( 'apply' === (string) ( $assoc['mode'] ?? 'draft' ) ? 'applied' : 'drafted' ) ) ); } public function diff( array $args, array $assoc ) { self::as_admin(); $specs = self::specs( (string) ( $args[0] ?? '' ) ); $reports = array(); foreach ( $specs as $file => $spec ) { $report = AIEO_Content_Compiler::diff( $spec, self::media_opts( $assoc, $file ) ); if ( is_wp_error( $report ) ) { WP_CLI::warning( sprintf( '%s: %s', basename( $file ), $report->get_error_message() ) ); continue; } $reports[] = $report; self::print_report( $report, (string) ( $assoc['format'] ?? 'table' ) ); } if ( 'json' === (string) ( $assoc['format'] ?? '' ) ) { WP_CLI::line( (string) wp_json_encode( $reports, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ); } } public function export( array $args, array $assoc ) { self::as_admin(); $spec = AIEO_Content_Exporter::export( (string) ( $args[0] ?? '' ) ); if ( is_wp_error( $spec ) ) { WP_CLI::error( $spec->get_error_message() ); } $json = (string) wp_json_encode( $spec, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n"; if ( ! empty( $assoc['out'] ) ) { if ( false === file_put_contents( (string) $assoc['out'], $json ) ) { WP_CLI::error( sprintf( 'Cannot write %s.', (string) $assoc['out'] ) ); } WP_CLI::success( sprintf( 'Exported %s to %s.', (string) $spec['key'], (string) $assoc['out'] ) ); return; } WP_CLI::line( $json ); } public function validate( array $args, array $assoc ) { $specs = self::specs( (string) ( $args[0] ?? '' ) ); $failed = 0; $warnings = 0; foreach ( $specs as $file => $spec ) { $check = AIEO_Content_Spec::validate( $spec, self::media_opts( $assoc, $file ) + array( 'check_files' => true ) ); foreach ( $check['warnings'] as $warning ) { WP_CLI::warning( sprintf( '%s: %s', basename( $file ), $warning ) ); } $warnings += count( $check['warnings'] ); foreach ( $check['errors'] as $error ) { WP_CLI::line( sprintf( 'ERROR %s: %s', basename( $file ), $error ) ); } if ( $check['errors'] || ( ! empty( $assoc['strict'] ) && $check['warnings'] ) ) { ++$failed; } else { WP_CLI::line( sprintf( 'OK %s: %d section(s), %d warning(s)', basename( $file ), count( (array) $spec['sections'] ), count( $check['warnings'] ) ) ); } } if ( $failed ) { WP_CLI::error( sprintf( '%d of %d spec(s) invalid.', $failed, count( $specs ) ) ); } WP_CLI::success( sprintf( '%d spec(s) valid, %d warning(s).', count( $specs ), $warnings ) ); } private static function media_opts( array $assoc, $file ) { return array( 'media_dir' => (string) ( $assoc['media-dir'] ?? AIEO_Content_Spec::content_dir( $file ) ), 'wp_content_dir' => (string) ( $assoc['wp-content-dir'] ?? '' ), 'strict' => ! empty( $assoc['strict'] ), ); } private static function specs( $path ) { if ( '' === $path ) { WP_CLI::error( 'Give a *.page.json file or a folder of them.' ); } $specs = AIEO_Content_Spec::load( $path ); if ( is_wp_error( $specs ) ) { WP_CLI::error( $specs->get_error_message() ); } return $specs; } public static function as_admin() { if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) || get_current_user_id() ) { return; } $admins = get_users( array( 'role' => 'administrator', 'number' => 1, 'fields' => 'ID', 'orderby' => 'ID', 'order' => 'ASC' ) ); if ( $admins ) { wp_set_current_user( (int) $admins[0] ); } } private static function print_report( array $report, $format ) { if ( 'json' === $format ) { return; } WP_CLI::line( sprintf( '%s: page %s (%s%s)', $report['key'], $report['page_id'] ?: 'new', $report['mode'], ! empty( $report['adopted'] ) ? ', adopted by slug' : '' ) ); $rows = array(); foreach ( (array) $report['actions'] as $key => $action ) { $rows[] = array( 'section' => $key, 'action' => $action ); } if ( $rows ) { WP_CLI\Utils\format_items( 'table', $rows, array( 'section', 'action' ) ); } foreach ( (array) ( $report['warnings'] ?? array() ) as $warning ) { WP_CLI::warning( $warning ); } if ( ! empty( $report['conflicts'] ) ) { WP_CLI::warning( 'Conflicts (edited on the page and changed in the spec; --force=' . implode( ',', $report['conflicts'] ) . ' overrides): ' . implode( ', ', $report['conflicts'] ) ); } if ( ! empty( $report['kept'] ) ) { WP_CLI::warning( 'Kept although gone from the spec (edited on the page): ' . implode( ', ', $report['kept'] ) ); } if ( ! empty( $report['media'] ) ) { WP_CLI::line( 'Media to sideload: ' . implode( ', ', $report['media'] ) ); } if ( ! empty( $report['sideloaded'] ) ) { WP_CLI::line( 'Sideloaded: ' . implode( ', ', $report['sideloaded'] ) ); } foreach ( array( 'preview_url' => 'Preview', 'edit_url' => 'Edit', 'revision_id' => 'Previous state: revision', 'undo_token' => 'Undo token', 'note' => 'Note' ) as $key => $label ) { if ( ! empty( $report[ $key ] ) ) { WP_CLI::line( $label . ': ' . $report[ $key ] ); } } } } final class AIEO_Content_CLI_Menu { public function apply( array $args, array $assoc ) { AIEO_Content_CLI_Page::as_admin(); $data = AIEO_Content_Menus::read( (string) ( $args[0] ?? '' ) ); if ( is_wp_error( $data ) ) { WP_CLI::error( $data->get_error_message() ); } $report = AIEO_Content_Menus::apply( $data, array( 'mode' => (string) ( $assoc['mode'] ?? 'draft' ), 'dry_run' => ! empty( $assoc['dry-run'] ), 'strict' => ! empty( $assoc['strict'] ) ) ); if ( is_wp_error( $report ) ) { WP_CLI::error( $report->get_error_message() ); } foreach ( (array) ( $report['warnings'] ?? array() ) as $warning ) { WP_CLI::warning( $warning ); } if ( 'json' === (string) ( $assoc['format'] ?? '' ) ) { WP_CLI::line( (string) wp_json_encode( $report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ); return; } $rows = array(); foreach ( $report['menus'] as $row ) { $rows[] = array( 'menu' => $row['slug'], 'action' => $row['action'] ?? '', 'id' => $row['id'] ?? '', 'links' => $row['links'], 'left out' => implode( ', ', $row['left_out'] ), 'error' => $row['error'] ?? '', ); } WP_CLI\Utils\format_items( 'table', $rows, array( 'menu', 'action', 'id', 'links', 'left out', 'error' ) ); WP_CLI::success( sprintf( '%d menu(s) %s.', count( $report['menus'] ), 'apply' === $report['mode'] ? 'written' : 'planned' ) ); } } final class AIEO_Content_CLI_Form { public function apply( array $args, array $assoc ) { AIEO_Content_CLI_Page::as_admin(); if ( ! class_exists( 'AIEO_Form_CPT' ) ) { WP_CLI::error( 'Rooster One\'s forms (AIEO_Form_CPT) are not loaded on this site.' ); } $files = AIEO_Content_Forms::read( (string) ( $args[0] ?? '' ) ); if ( is_wp_error( $files ) ) { WP_CLI::error( $files->get_error_message() ); } $reports = array(); $failed = 0; foreach ( $files as $file => $def ) { $report = AIEO_Content_Forms::apply( $def, ! empty( $assoc['dry-run'] ) ); $report['file'] = basename( (string) $file ); foreach ( array_merge( $report['warnings'], $report['errors'] ) as $line ) { WP_CLI::warning( $report['file'] . ': ' . $line ); } $failed += $report['errors'] ? 1 : 0; $reports[] = $report; } if ( 'json' === (string) ( $assoc['format'] ?? '' ) ) { WP_CLI::line( (string) wp_json_encode( $reports, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ); } else { WP_CLI\Utils\format_items( 'table', array_map( static fn ( $r ) => array( 'file' => $r['file'], 'form' => $r['key'], 'action' => $r['action'], 'id' => $r['id'] ), $reports ), array( 'file', 'form', 'action', 'id' ) ); } if ( $failed ) { WP_CLI::error( sprintf( '%d form file(s) refused.', $failed ) ); } WP_CLI::success( sprintf( '%d form(s) %s.', count( $reports ), ! empty( $assoc['dry-run'] ) ? 'planned' : 'applied' ) ); } }