diff --git a/src/wp-admin/js/customize-controls.js b/src/wp-admin/js/customize-controls.js index 782973a9cb..e15f10cf58 100644 --- a/src/wp-admin/js/customize-controls.js +++ b/src/wp-admin/js/customize-controls.js @@ -2986,12 +2986,21 @@ * @returns {void} */ attachEvents: function() { - var panel = this, toggleDisabledNotification; + var panel = this; // Attach regular panel events. api.Panel.prototype.attachEvents.apply( panel ); - toggleDisabledNotification = function() { + // Temporary since supplying SFTP credentials does not work yet. See #42184 + if ( api.settings.theme._filesystemCredentialsNeeded ) { + panel.notifications.add( new api.Notification( 'theme_install_unavailable', { + message: api.l10n.themeInstallUnavailable, + type: 'info', + dismissible: true + } ) ); + } + + function toggleDisabledNotifications() { if ( 'publish' === api.state( 'selectedChangesetStatus' ).get() ) { panel.notifications.remove( 'theme_switch_unavailable' ); } else { @@ -3000,9 +3009,9 @@ type: 'warning' } ) ); } - }; - toggleDisabledNotification(); - api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotification ); + } + toggleDisabledNotifications(); + api.state( 'selectedChangesetStatus' ).bind( toggleDisabledNotifications ); // Collapse panel to customize the current theme. panel.contentContainer.on( 'click', '.customize-theme', function() { @@ -3096,6 +3105,14 @@ var panel = this, preview, onInstallSuccess, slug = $( event.target ).data( 'slug' ), deferred = $.Deferred(), request; preview = $( event.target ).hasClass( 'preview' ); + // Temporary since supplying SFTP credentials does not work yet. See #42184. + if ( api.settings.theme._filesystemCredentialsNeeded ) { + deferred.reject({ + errorCode: 'theme_install_unavailable' + }); + return deferred.promise(); + } + // Prevent loading a non-active theme preview when there is a drafted/scheduled changeset. if ( 'publish' !== api.state( 'selectedChangesetStatus' ).get() && slug !== api.settings.theme.stylesheet ) { deferred.reject({ @@ -3296,6 +3313,11 @@ event.preventDefault(); + // Temporary since supplying SFTP credentials does not work yet. See #42184. + if ( api.settings.theme._filesystemCredentialsNeeded ) { + return; + } + // Confirmation dialog for deleting a theme. if ( ! window.confirm( api.settings.l10n.confirmDeleteTheme ) ) { return; @@ -4983,16 +5005,25 @@ * @since 4.2.0 */ ready: function() { - var control = this, disableSwitchButtons, updateButtons; + var control = this; - disableSwitchButtons = function() { + function disableSwitchButtons() { return 'publish' !== api.state( 'selectedChangesetStatus' ).get() && control.params.theme.id !== api.settings.theme.stylesheet; - }; - updateButtons = function() { - control.container.find( 'button' ).toggleClass( 'disabled', disableSwitchButtons() ); - }; + } - api.state( 'selectedChangesetStatus' ).bind( updateButtons ); + // Temporary special function since supplying SFTP credentials does not work yet. See #42184. + function disableInstallButtons() { + return disableSwitchButtons() || true === api.settings.theme._filesystemCredentialsNeeded; + } + function updateButtons( container ) { + var _container = container || control.container; + _container.find( 'button.preview, button.preview-theme' ).toggleClass( 'disabled', disableSwitchButtons() ); + _container.find( 'button.theme-install' ).toggleClass( 'disabled', disableInstallButtons() ); + } + + api.state( 'selectedChangesetStatus' ).bind( function() { + updateButtons(); + }); updateButtons(); control.container.on( 'touchmove', '.theme', function() { @@ -5019,7 +5050,12 @@ event.preventDefault(); // Keep this AFTER the key filter above section = api.section( control.section() ); section.showDetails( control.params.theme, function() { - section.overlay.find( '.theme-actions button' ).toggleClass( 'disabled', disableSwitchButtons() ); + updateButtons( section.overlay.find( '.theme-actions' ) ); + + // Temporary special function since supplying SFTP credentials does not work yet. See #42184. + if ( api.settings.theme._filesystemCredentialsNeeded ) { + section.overlay.find( '.theme-actions .delete-theme' ).remove(); + } } ); }); diff --git a/src/wp-includes/class-wp-customize-manager.php b/src/wp-includes/class-wp-customize-manager.php index 9127650a13..be3115f3ba 100644 --- a/src/wp-includes/class-wp-customize-manager.php +++ b/src/wp-includes/class-wp-customize-manager.php @@ -4618,6 +4618,15 @@ final class WP_Customize_Manager { ), ); + // Temporarily disable installation in Customizer. See #42184. + $filesystem_method = get_filesystem_method(); + ob_start(); + $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); + ob_end_clean(); + if ( 'direct' !== $filesystem_method && ! $filesystem_credentials_are_stored ) { + $settings['theme']['_filesystemCredentialsNeeded'] = true; + } + // Prepare Customize Section objects to pass to JavaScript. foreach ( $this->sections() as $id => $section ) { if ( $section->check_capabilities() ) { diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 96ecd1dacd..753038dd37 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -593,6 +593,11 @@ function wp_default_scripts( &$scripts ) { ), 'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ), 'themePreviewUnavailable' => __( 'Sorry, you can’t preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.' ), + 'themeInstallUnavailable' => sprintf( + /* translators: %s is URL to Add Themes admin screen */ + __( 'You won’t be able to install new themes from here yet since your install requires SFTP credentials. For now, please add themes in the admin.' ), + esc_url( admin_url( 'theme-install.php' ) ) + ), ) ); $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );