Make WordPress Core


Ignore:
Timestamp:
05/20/2020 06:47:24 PM (5 years ago)
Author:
whyisjake
Message:

Security: Add user interface to auto-update themes and plugins.

Building on core update mechanisms, this adds the ability to enable automatic updates for themes and plugins to the WordPress admin.

Fixes: #50052.
Props: afercia, afragen, audrasjb, azaozz, bookdude13, davidperonne, desrosj, gmays, gmays, javiercasares, karmatosed, knutsp, mapk, mukesh27, netweb, nicolaskulka, nielsdeblaauw, paaljoachim, passoniate, pbiron, pedromendonca, whodunitagency, whyisjake, wpamitkumar, and xkon.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/network/themes.php

    r47198 r47835  
    2323
    2424// Clean up request URI from temporary args for screen options/paging uri's to work as expected.
    25 $temp_args              = array( 'enabled', 'disabled', 'deleted', 'error' );
     25$temp_args = array(
     26    'enabled',
     27    'disabled',
     28    'deleted',
     29    'error',
     30    'enabled-auto-update',
     31    'disabled-auto-update',
     32);
     33
    2634$_SERVER['REQUEST_URI'] = remove_query_arg( $temp_args, $_SERVER['REQUEST_URI'] );
    2735$referer                = remove_query_arg( $temp_args, wp_get_referer() );
     
    124132                $themes_to_delete = count( $themes );
    125133                ?>
    126             <div class="wrap">
    127                 <?php if ( 1 == $themes_to_delete ) : ?>
     134                <div class="wrap">
     135                <?php if ( 1 === $themes_to_delete ) : ?>
    128136                    <h1><?php _e( 'Delete Theme' ); ?></h1>
    129137                    <div class="error"><p><strong><?php _e( 'Caution:' ); ?></strong> <?php _e( 'This theme may be active on other sites in the network.' ); ?></p></div>
     
    146154                    ?>
    147155                    </ul>
    148                 <?php if ( 1 == $themes_to_delete ) : ?>
     156                <?php if ( 1 === $themes_to_delete ) : ?>
    149157                    <p><?php _e( 'Are you sure you want to delete this theme?' ); ?></p>
    150158                <?php else : ?>
     
    155163                    <input type="hidden" name="action" value="delete-selected" />
    156164                    <?php
     165
    157166                    foreach ( (array) $themes as $theme ) {
    158167                        echo '<input type="hidden" name="checked[]" value="' . esc_attr( $theme ) . '" />';
    159168                    }
    160169
    161                         wp_nonce_field( 'bulk-themes' );
    162 
    163                     if ( 1 == $themes_to_delete ) {
     170                    wp_nonce_field( 'bulk-themes' );
     171
     172                    if ( 1 === $themes_to_delete ) {
    164173                        submit_button( __( 'Yes, delete this theme' ), '', 'submit', false );
    165174                    } else {
    166175                        submit_button( __( 'Yes, delete these themes' ), '', 'submit', false );
    167176                    }
     177
    168178                    ?>
    169179                </form>
    170                 <?php
    171                 $referer = wp_get_referer();
    172                 ?>
     180                <?php $referer = wp_get_referer(); ?>
    173181                <form method="post" action="<?php echo $referer ? esc_url( $referer ) : ''; ?>" style="display:inline;">
    174182                    <?php submit_button( __( 'No, return me to the theme list' ), '', 'submit', false ); ?>
    175183                </form>
    176             </div>
     184                </div>
    177185                <?php
     186
    178187                require_once ABSPATH . 'wp-admin/admin-footer.php';
    179188                exit;
     
    209218            );
    210219            exit;
     220        case 'enable-auto-update':
     221        case 'disable-auto-update':
     222        case 'enable-auto-update-selected':
     223        case 'disable-auto-update-selected':
     224            if ( ! ( current_user_can( 'update_themes' ) && wp_is_auto_update_enabled_for_type( 'theme' ) ) ) {
     225                wp_die( __( 'Sorry, you are not allowed to change themes automatic update settings.' ) );
     226            }
     227
     228            if ( 'enable-auto-update' === $action || 'disable-auto-update' === $action ) {
     229                check_admin_referer( 'updates' );
     230            } else {
     231                if ( empty( $_POST['checked'] ) ) {
     232                    // Nothing to do.
     233                    wp_safe_redirect( add_query_arg( 'error', 'none', $referer ) );
     234                    exit;
     235                }
     236
     237                check_admin_referer( 'bulk-themes' );
     238            }
     239
     240            $auto_updates = (array) get_site_option( 'auto_update_themes', array() );
     241
     242            if ( 'enable-auto-update' === $action ) {
     243                $auto_updates[] = $_GET['theme'];
     244                $auto_updates   = array_unique( $auto_updates );
     245                $referer        = add_query_arg( 'enabled-auto-update', 1, $referer );
     246            } elseif ( 'disable-auto-update' === $action ) {
     247                $auto_updates = array_diff( $auto_updates, array( $_GET['theme'] ) );
     248                $referer      = add_query_arg( 'disabled-auto-update', 1, $referer );
     249            } else {
     250                // Bulk enable/disable.
     251                $themes = (array) wp_unslash( $_POST['checked'] );
     252
     253                if ( 'enable-auto-update-selected' === $action ) {
     254                    $auto_updates = array_merge( $auto_updates, $themes );
     255                    $auto_updates = array_unique( $auto_updates );
     256                    $referer      = add_query_arg( 'enabled-auto-update', count( $themes ), $referer );
     257                } else {
     258                    $auto_updates = array_diff( $auto_updates, $themes );
     259                    $referer      = add_query_arg( 'disabled-auto-update', count( $themes ), $referer );
     260                }
     261            }
     262
     263            $all_items = wp_get_themes();
     264
     265            // Remove themes that don't exist or have been deleted since the option was last updated.
     266            $auto_updates = array_intersect( $auto_updates, array_keys( $all_items ) );
     267
     268            update_site_option( 'auto_update_themes', $auto_updates );
     269
     270            wp_safe_redirect( $referer );
     271            exit;
    211272        default:
    212273            $themes = isset( $_POST['checked'] ) ? (array) $_POST['checked'] : array();
     
    285346if ( isset( $_GET['enabled'] ) ) {
    286347    $enabled = absint( $_GET['enabled'] );
    287     if ( 1 == $enabled ) {
     348    if ( 1 === $enabled ) {
    288349        $message = __( 'Theme enabled.' );
    289350    } else {
     
    294355} elseif ( isset( $_GET['disabled'] ) ) {
    295356    $disabled = absint( $_GET['disabled'] );
    296     if ( 1 == $disabled ) {
     357    if ( 1 === $disabled ) {
    297358        $message = __( 'Theme disabled.' );
    298359    } else {
     
    303364} elseif ( isset( $_GET['deleted'] ) ) {
    304365    $deleted = absint( $_GET['deleted'] );
    305     if ( 1 == $deleted ) {
     366    if ( 1 === $deleted ) {
    306367        $message = __( 'Theme deleted.' );
    307368    } else {
     
    310371    }
    311372    echo '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $deleted ) ) . '</p></div>';
    312 } elseif ( isset( $_GET['error'] ) && 'none' == $_GET['error'] ) {
     373} elseif ( isset( $_GET['enabled-auto-update'] ) ) {
     374    $enabled = absint( $_GET['enabled-auto-update'] );
     375    if ( 1 === $enabled ) {
     376        $message = __( 'Theme will be auto-updated.' );
     377    } else {
     378        /* translators: %s: Number of themes. */
     379        $message = _n( '%s theme will be auto-updated.', '%s themes will be auto-updated.', $enabled );
     380    }
     381    echo '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $enabled ) ) . '</p></div>';
     382} elseif ( isset( $_GET['disabled-auto-update'] ) ) {
     383    $disabled = absint( $_GET['disabled-auto-update'] );
     384    if ( 1 === $disabled ) {
     385        $message = __( 'Theme will no longer be auto-updated.' );
     386    } else {
     387        /* translators: %s: Number of themes. */
     388        $message = _n( '%s theme will no longer be auto-updated.', '%s themes will no longer be auto-updated.', $disabled );
     389    }
     390    echo '<div id="message" class="updated notice is-dismissible"><p>' . sprintf( $message, number_format_i18n( $disabled ) ) . '</p></div>';
     391} elseif ( isset( $_GET['error'] ) && 'none' === $_GET['error'] ) {
    313392    echo '<div id="message" class="error notice is-dismissible"><p>' . __( 'No theme selected.' ) . '</p></div>';
    314 } elseif ( isset( $_GET['error'] ) && 'main' == $_GET['error'] ) {
     393} elseif ( isset( $_GET['error'] ) && 'main' === $_GET['error'] ) {
    315394    echo '<div class="error notice is-dismissible"><p>' . __( 'You cannot delete a theme while it is active on the main site.' ) . '</p></div>';
    316395}
     
    325404$wp_list_table->views();
    326405
    327 if ( 'broken' == $status ) {
     406if ( 'broken' === $status ) {
    328407    echo '<p class="clear">' . __( 'The following themes are installed but incomplete.' ) . '</p>';
    329408}
Note: See TracChangeset for help on using the changeset viewer.