Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ jobs:

- uses: Extra-Chill/homeboy-action@31e95050206332c4ebd36894387c980c99443ecf # v2.8.15
with:
# Pin homeboy core to 0.330.0: core 0.331.0+ (PR #11553) validates
# the `test.failures` sidecar as a JSON array, but the wordpress
# extension's wp-codebox adapter still emits an object sidecar.
# Remove this pin once the extension ships an array sidecar.
version: 0.330.0
commands: review lint
args: --extension wordpress
php-version: '8.2'
Expand All @@ -49,6 +54,8 @@ jobs:

- uses: Extra-Chill/homeboy-action@31e95050206332c4ebd36894387c980c99443ecf # v2.8.15
with:
# Pin homeboy core to 0.330.0: see lint step for the rationale.
version: 0.330.0
commands: review test
args: --extension wordpress
php-version: ${{ matrix.php-version }}
Expand Down
28 changes: 0 additions & 28 deletions TESTING_INSTRUCTIONS.md

This file was deleted.

69 changes: 48 additions & 21 deletions blocks/importer/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,10 @@
const uploadInputs = root.querySelectorAll( '[data-static-site-importer-source-files], [data-static-site-importer-source-directory]' );
const provider = root.getAttribute( 'data-static-site-importer-provider' ) || '';
const isCurrentSiteImport = root.getAttribute( 'data-static-site-importer-apply-to-current-site' ) === '1';
const initialUrl = form ? form.getAttribute( 'data-static-site-importer-default-url' ) || '' : '';
const isUrlOnly = '' !== initialUrl && ! html.value && 0 === uploadInputs.length;
const source = {
url: form ? form.getAttribute( 'data-static-site-importer-default-url' ) || '' : '',
url: initialUrl,
html: html ? html.value : '',
files: await buildFiles( uploadInputs, root ),
archive: await buildArchive( uploadInputs, root ),
Expand All @@ -352,34 +354,59 @@
try {
const restUrl = root.getAttribute( 'data-static-site-importer-rest-url' );
const nonce = root.getAttribute( 'data-static-site-importer-nonce' );
const response = await fetch( restUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
body: JSON.stringify( {
provider,
source,
const postImport = async function ( importSource, importId ) {
const body = {
source: importSource,
apply_to_current_site: isCurrentSiteImport,
activate: isCurrentSiteImport,
overwrite: isCurrentSiteImport,
} ),
} );
const report = await response.json();
};
if ( importId ) {
body.source = Object.assign( {}, importSource, { import_id: importId } );
}
if ( ! isUrlOnly && '' !== provider ) {
body.provider = provider;
}
return fetch( restUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': nonce,
},
body: JSON.stringify( body ),
} );
};

let response = await postImport( source, '' );
let report = await response.json();

if ( isUrlOnly && response.ok && report.continuation === true ) {
const maxContinuations = 64;
let steps = 0;
while ( response.ok && report.continuation === true && ! report.error && steps < maxContinuations ) {
steps++;
const nextUrl = report.url || source.url;
const nextImportId = report.import_id || '';
showStatus( root, 'Continuing URL import (' + steps + ')...' );
response = await postImport( { url: nextUrl }, nextImportId );
report = await response.json();
}
}

setReport( root, report );
if ( response.ok && isCurrentSiteImport && report.success ) {

if ( ! response.ok ) {
showStatus( root, ( report.error && report.error.message ) ? report.error.message : 'Import request failed.' );
} else if ( isCurrentSiteImport && report.success ) {
showStatus( root, 'Import complete.' );
} else if ( response.ok && report.success && previewUrl( report ) ) {
} else if ( report.success && previewUrl( report ) ) {
openPreview( report );
showStatus( root, 'WordPress Playground opened.' );
} else if ( response.ok && previewUrl( report ) ) {
openPreview( report );
showStatus( root, 'Preview opened.' );
} else if ( response.ok && report.preview && report.preview.status === 'unavailable' ) {
showStatus( root, report.preview.message || 'Preview unavailable: WP Codebox did not return a preview URL or Playground blueprint URL.' );
} else if ( report.success && report.preview && 'unavailable' === report.preview.status ) {
const requirement = report.preview.requires_ability_capable_target;
showStatus( root, requirement ? ( report.preview.message || 'URL preview needs a disposable WordPress target that exposes the import-url ability.' ) : ( report.preview.message || 'Preview unavailable: WP Codebox did not return a preview URL or Playground blueprint URL.' ) );
} else {
showStatus( root, response.ok && report.success ? 'Preview request complete.' : 'Preview request failed.' );
showStatus( root, report.success ? 'Preview request complete.' : 'Preview request failed.' );
}
} catch ( error ) {
setReport( root, { success: false, error: { message: error.message } } );
Expand Down
1 change: 1 addition & 0 deletions homeboy-test-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"tests/smoke-template-chrome-dedupe.php": { "environment": "standalone-php" },
"tests/smoke-template-part-shell-dedupe.php": { "environment": "standalone-php" },
"tests/smoke-url-import-runtime.php": { "environment": "standalone-php" },
"tests/smoke-rest-url-import-helpers.php": { "environment": "standalone-php" },
"tests/smoke-url-concurrent-fetcher.php": { "environment": "standalone-php" },
"tests/smoke-validation-runtime-diagnostics.php": { "environment": "standalone-php" },
"tests/smoke-visual-repair-css.php": { "environment": "standalone-php" },
Expand Down
93 changes: 0 additions & 93 deletions includes/class-static-site-importer-url-import-runtime.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,35 +87,6 @@ public static function import_url( array $input ) {
return Static_Site_Importer_Theme_Generator::import_website_artifact( $runtime['artifact'], $args );
}

/**
* Resolve a URL into a website artifact without importing it.
*
* @param array<string,mixed> $input Ability-style input.
* @return array<string,mixed>|WP_Error Runtime output containing artifact/source_metadata/provider.
*/
public static function website_artifact_from_url( array $input ) {
$url = isset( $input['url'] ) ? Static_Site_Importer_URL_Fetcher::normalize_url( (string) $input['url'] ) : '';
if ( '' === $url ) {
return new WP_Error( 'static_site_importer_missing_url', 'The url input is required.' );
}

$input['url'] = $url;
$request = self::provider_request( $url, $input );
$runtime = self::resolve_provider( $request );
if ( is_wp_error( $runtime ) ) {
return $runtime;
}

$artifact = isset( $runtime['artifact'] ) && is_array( $runtime['artifact'] ) ? $runtime['artifact'] : array();
if ( empty( $artifact ) ) {
return new WP_Error( 'static_site_importer_url_provider_missing_artifact', 'The URL import provider did not return a website artifact.' );
}

$runtime['artifact'] = $artifact;

return $runtime;
}

/**
* Build a provider request envelope.
*
Expand All @@ -133,23 +104,6 @@ private static function provider_request( string $url, array $input ): array {
);
}

/**
* Resolve the provider output.
*
* Providers return an array with an `artifact` key containing a website
* artifact, plus optional `source_metadata` and `provider` fields.
*
* @param array<string,mixed> $request Provider request envelope.
* @return array<string,mixed>|WP_Error
*/
private static function resolve_provider( array $request ) {
$provider_output = self::provider_output( $request );
if ( is_wp_error( $provider_output ) || is_array( $provider_output ) ) {
return $provider_output;
}
return self::fetch_public_url_provider( $request );
}

/** @return null|array<string,mixed>|WP_Error */
private static function provider_output( array $request ) {
/**
Expand All @@ -165,53 +119,6 @@ private static function provider_output( array $request ) {
return apply_filters( 'static_site_importer_url_import_provider', null, $request );
}

/**
* Built-in generic public URL provider.
*
* @param array<string,mixed> $request Provider request envelope.
* @return array<string,mixed>|WP_Error
*/
private static function fetch_public_url_provider( array $request ) {
$provider_args = isset( $request['provider_args'] ) && is_array( $request['provider_args'] ) ? $request['provider_args'] : array();
if ( ! empty( $provider_args['collect_site'] ) ) {
$provider_args['require_complete_collection'] = true;
return Static_Site_Importer_URL_Site_Collector::collect( (string) $request['url'], $provider_args );
}

$fetch = Static_Site_Importer_URL_Fetcher::fetch_to_work_dir(
(string) $request['url'],
(string) $request['work_dir'],
$provider_args
);
if ( is_wp_error( $fetch ) ) {
return $fetch;
}

$html = file_get_contents( $fetch['html_path'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reads the importer-owned fetched HTML artifact.
if ( false === $html ) {
return new WP_Error( 'static_site_importer_url_artifact_read_failed', 'Failed to read fetched URL HTML.' );
}
$normalized = Static_Site_Importer_Source_Normalizer::normalize_html( $html, (string) $request['url'], $provider_args );
$html = $normalized['html'];
$metadata = $fetch['metadata'];
$metadata['source_exclusions'] = $normalized['exclusions'];
$metadata['diagnostics'] = array_merge( is_array( $metadata['diagnostics'] ?? null ) ? $metadata['diagnostics'] : array(), $normalized['diagnostics'] );

return array(
'provider' => 'public-url-fetcher',
'artifact' => array(
'schema' => 'blocks-engine/php-transformer/site-artifact/v1',
'files' => array(
array(
'path' => 'website/index.html',
'content' => $html,
),
),
),
'source_metadata' => $metadata,
);
}

/**
* Build import args for the normal website artifact importer.
*
Expand Down
Loading
Loading