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
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,19 @@ public static function display() {
</small>
</div>

<div id="plugin-check-preview" class="plugin-check-preview" hidden>
<p>
<button type="button" id="plugin-check-preview-button" class="wp-block-button__link">
<?php esc_html_e( 'Test with Plugin Check in Playground', 'wporg-plugins' ); ?>
</button>
<br>
<small>
<?php esc_html_e( 'Runs the selected zip through the Plugin Check plugin, inside a WordPress Playground running in your browser. Your zip is not uploaded to WordPress.org for this.', 'wporg-plugins' ); ?>
</small>
</p>
<div class="plugin-check-preview-frame" hidden></div>
</div>

<p>
<label>
<?php _e( 'Additional Information', 'wporg-plugins' ); ?><br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,121 @@
$(this).hide().parents('ul').find('.plugin-upload-form.hidden').removeClass( 'hidden' );
} );

// Pre-submission Plugin Check, in an embedded WordPress Playground.
var $uploadForm = $( '#upload_form' ),
$fileInput = $uploadForm.find( 'input.plugin-file' ),
$preview = $( '#plugin-check-preview' ),
$previewButton = $( '#plugin-check-preview-button' ),
$frameContainer = $preview.find( '.plugin-check-preview-frame' );

// Runs in Playground after boot: return the basename (e.g. "my-plugin/my-plugin.php")
// of the just-installed plugin, so we can preselect it in the Plugin Check dropdown.
// Plugin Check matches ?plugin= against the full basename, not just the folder name.
var detectPluginBasename = [
'<?php',
'require "/wordpress/wp-load.php";',
'require_once ABSPATH . "wp-admin/includes/plugin.php";',
'$exclude = array( "akismet/akismet.php", "hello.php" );',
'$targets = array();',
'foreach ( array_keys( get_plugins() ) as $basename ) {',
' if ( in_array( $basename, $exclude, true ) || false !== strpos( $basename, "plugin-check" ) ) {',
' continue;',
' }',
' $targets[] = $basename;',
'}',
'echo 1 === count( $targets ) ? $targets[0] : "";'
].join( '\n' );

if ( $uploadForm.length && $preview.length ) {
$fileInput.on( 'change', function() {
// Reveal the button once a zip is selected; reset any earlier Playground run.
$preview.prop( 'hidden', ! this.files.length );
$frameContainer.prop( 'hidden', true ).empty();
$previewButton.prop( 'disabled', false );
} );

$previewButton.on( 'click', async function() {
var file = $fileInput[0].files[0],
buttonText = $previewButton.text();

if ( ! file ) {
return;
}

$previewButton.prop( 'disabled', true ).text( wp.i18n ? wp.i18n.__( 'Loading Playground…', 'wporg-plugins' ) : 'Loading Playground…' );

try {
var playgroundApi = await import( /* webpackIgnore: true */ 'https://playground.wordpress.net/client/index.js' ),
zipBytes = new Uint8Array( await file.arrayBuffer() ),
iframe = document.createElement( 'iframe' );
Comment thread
akirk marked this conversation as resolved.

iframe.className = 'plugin-check-preview-iframe';
iframe.title = wp.i18n ? wp.i18n.__( 'Plugin Check preview (WordPress Playground)', 'wporg-plugins' ) : 'Plugin Check preview (WordPress Playground)';
iframe.style.cssText = 'width: 100%; height: 80vh; border: 1px solid #c3c4c7; border-radius: 2px';

$frameContainer.prop( 'hidden', false ).empty().append( iframe );
iframe.scrollIntoView( { behavior: 'smooth', block: 'nearest' } );
Comment thread
akirk marked this conversation as resolved.

var client = await playgroundApi.startPlaygroundWeb( {
iframe: iframe,
remoteUrl: 'https://playground.wordpress.net/remote.html',
blueprint: {
landingPage: '/wp-admin/admin.php?page=plugin-check',
preferredVersions: {
php: '7.4', // Minimum recommended PHP, as with the server-generated blueprints.
wp: 'latest'
},
features: {
networking: true
},
steps: [
{
step: 'login',
username: 'admin',
password: 'password'
},
{
step: 'installPlugin',
pluginData: {
resource: 'wordpress.org/plugins',
slug: 'plugin-check'
}
},
{
step: 'installPlugin',
pluginData: {
resource: 'literal',
name: file.name,
contents: zipBytes
},
options: {
activate: false
}
}
]
}
} );

// Preselect the uploaded plugin in the Plugin Check dropdown by its basename.
// The user still clicks "Check it!" themselves.
try {
var result = await client.run( { code: detectPluginBasename } ),
basename = ( result.text || '' ).trim();

if ( basename ) {
await client.goTo( '/wp-admin/admin.php?page=plugin-check&plugin=' + encodeURIComponent( basename ) );
}
} catch ( selectError ) {
// Preselection is best-effort; the dropdown still lets the user pick manually.
}

$previewButton.prop( 'disabled', false ).text( buttonText );
} catch ( error ) {
$frameContainer.prop( 'hidden', true ).empty();
$previewButton.prop( 'disabled', false ).text( buttonText );
window.alert( 'WordPress Playground could not be loaded: ' + ( error.message || error ) );
}
} );
}

})( jQuery );
Loading