'administrator', 'number' => 1, 'fields' => 'ID']); if (!$admins) { WP_CLI::error('This site has no administrator account. An import needs one to attribute authors and sideload media.'); } wp_set_current_user((int) $admins[0]); } foreach (['file.php', 'media.php', 'image.php'] as $f) { require_once ABSPATH . 'wp-admin/includes/' . $f; } $started = microtime(true); $opts = [ 'siteIdentity' => !empty($assoc['site-identity']), 'componentsOnly' => !empty($assoc['components-only']), 'dryRun' => !empty($assoc['dry-run']), ]; try { $res = Kit\Package::import($zip, $opts); } catch (\Throwable $e) { WP_CLI::error(sprintf('The import threw an exception: %s', $e->getMessage())); } if (empty($res['ok'])) { WP_CLI::error(sprintf('The import failed: %s', $res['error'] ?? 'the package could not be parsed')); } $warnings = (array) ($res['warnings'] ?? []); $secs = round(microtime(true) - $started, 1); $stats = [ 'site' => get_current_blog_id(), 'url' => home_url('/'), 'contentModel' => (int) ($res['contentModel'] ?? 0), 'terms' => (int) ($res['terms'] ?? 0), 'posts' => (int) ($res['posts'] ?? 0), 'media' => (int) ($res['media'] ?? 0), 'library' => (int) ($res['library'] ?? 0), 'templates' => (int) ($res['templates'] ?? 0), 'menus' => (int) ($res['menus'] ?? 0), 'warnings' => count($warnings), 'seconds' => $secs, ]; foreach ($warnings as $w) { WP_CLI::warning((string) $w); } if (!empty($assoc['porcelain'])) { WP_CLI::line(wp_json_encode($stats)); WP_CLI::halt(0); } WP_CLI::success(sprintf( '%s - content %d, terms %d, media %d, components %d, templates %d, menus %d, warnings %d (%ss)', $stats['url'], $stats['posts'], $stats['terms'], $stats['media'], (int) ($stats['library'] ?? 0), $stats['templates'], $stats['menus'], $stats['warnings'], $secs )); } public function kit_requires($args, $assoc) { $zip = $args[0] ?? ''; if ($zip === '' || !is_readable($zip)) { WP_CLI::error(sprintf('Cannot read that package: %s', $zip)); } if (!class_exists('\ZipArchive')) { throw new \RuntimeException('This needs PHP\'s zip extension (ZipArchive), which is not installed on this server.'); } $za = new \ZipArchive(); if ($za->open($zip) !== true) { WP_CLI::error('That package could not be opened.'); } $json = $za->getFromName('kit.json'); $za->close(); if ($json === false) { WP_CLI::error('The package contains no kit.json.'); } $kit = json_decode((string) $json); $req = $kit->requires ?? null; $out = [ 'kit' => (string) ($kit->meta->slug ?? ''), 'version' => (string) ($kit->meta->version ?? ''), 'theme' => (string) ($req->theme ?? ''), 'plugins' => array_values(array_map('strval', (array) ($req->plugins ?? []))), 'optional' => array_values(array_map('strval', (array) ($req->optional ?? []))), ]; if (!empty($assoc['porcelain'])) { WP_CLI::line(wp_json_encode($out)); WP_CLI::halt(0); } WP_CLI::line(sprintf('%s %s - theme %s, plugins %s', $out['kit'], $out['version'], $out['theme'], $out['plugins'] ? implode(' ', $out['plugins']) : '(no additional dependencies)')); } public function doctor($args, $assoc) { $urls = Kit\Importer::audit_foreign_uploads(); $col = Kit\Importer::audit_collapsed_instances(); $known = get_option('aumframe_kit_components', null); $cmp = is_array($known) && $known ? Kit\Importer::audit_stray_components( array_map(static function ($slug) { return (object) ['slug' => $slug]; }, $known) ) : null; if (!empty($assoc['porcelain'])) { WP_CLI::line((string) wp_json_encode([ 'foreignUploads' => $urls, 'strayComponents' => $cmp, 'collapsedInstances' => $col, ])); WP_CLI::halt($urls['foreign'] > 0 || ($cmp && $cmp['stray'] > 0) || $col['collapsed'] > 0 ? 1 : 0); } WP_CLI::line(sprintf( 'Image URLs scanned %d, pointing off-site %d%s', $urls['scanned'], $urls['foreign'], $urls['hosts'] ? '(' . implode('、', $urls['hosts']) . ')' : '' )); foreach ($urls['samples'] as $u) { WP_CLI::line(' ' . $u); } if ($cmp === null) { WP_CLI::line('Components this site has no record of which kit it has, so this section cannot be answered (no kit was ever imported, or it was imported before 1.33.0)'); } else { WP_CLI::line(sprintf( 'Components %d on this site, %d not belonging to this kit%s', $cmp['total'], $cmp['stray'], $cmp['slugs'] ? '(' . implode('、', array_slice($cmp['slugs'], 0, 10)) . ')' : '' )); } WP_CLI::line(sprintf( 'Designs scanned %d, with collapsed compiled output %d (across %d instances)%s', $col['scanned'], $col['collapsed'], $col['instances'], $col['slugs'] ? '(' . implode('、', $col['slugs']) . ')' : '' )); if ($col['collapsed'] > 0) { WP_CLI::line(' On those designs, component instances with per-node overrides render as the component itself, so several instances look identical.'); WP_CLI::line(' Fix: open each one in the editor and save it again. The design data was never wrong; only the compiled output is,'); WP_CLI::line(' and compiling happens only on save, so updating the plugin does not repair them on its own.'); } if ($urls['foreign'] === 0 && $urls['scanned'] === 0) { WP_CLI::warning('No image URL was scanned at all. Either this site has no designs, or this check is broken.'); } if ($col['scanned'] === 0) { WP_CLI::warning('No design was scanned at all. Either this site has no designs, or this check is broken.'); } if ($urls['foreign'] > 0 || ($cmp && $cmp['stray'] > 0) || $col['collapsed'] > 0) { WP_CLI::halt(1); } WP_CLI::success('No problems found.'); } }