WordPress.org

Make WordPress Core

Ticket #48491: 48491.2.diff

File 48491.2.diff, 13.2 KB (added by afragen, 23 months ago)

Precedence: API > readme.txt > style.css

  • wp-admin/includes/theme.php

    diff --git a/wp-admin/includes/theme.php b/wp-admin/includes/theme.php
    index 12035e1fc9..108da0e934 100644
    a b function wp_prepare_themes_for_js( $themes = null ) { 
    653653                }
    654654
    655655                $prepared_themes[ $slug ] = array(
    656                         'id'           => $slug,
    657                         'name'         => $theme->display( 'Name' ),
    658                         'screenshot'   => array( $theme->get_screenshot() ), // @todo multiple
    659                         'description'  => $theme->display( 'Description' ),
    660                         'author'       => $theme->display( 'Author', false, true ),
    661                         'authorAndUri' => $theme->display( 'Author' ),
    662                         'version'      => $theme->display( 'Version' ),
    663                         'tags'         => $theme->display( 'Tags' ),
    664                         'parent'       => $parent,
    665                         'active'       => $slug === $current_theme,
    666                         'hasUpdate'    => isset( $updates[ $slug ] ),
    667                         'hasPackage'   => isset( $updates[ $slug ] ) && ! empty( $updates[ $slug ]['package'] ),
    668                         'update'       => get_theme_update_available( $theme ),
    669                         'actions'      => array(
     656                        'id'             => $slug,
     657                        'name'           => $theme->display( 'Name' ),
     658                        'screenshot'     => array( $theme->get_screenshot() ), // @todo multiple
     659                        'description'    => $theme->display( 'Description' ),
     660                        'author'         => $theme->display( 'Author', false, true ),
     661                        'authorAndUri'   => $theme->display( 'Author' ),
     662                        'version'        => $theme->display( 'Version' ),
     663                        'tags'           => $theme->display( 'Tags' ),
     664                        'requires'       => $theme->display( 'Requires' ),
     665                        'requires_php'   => $theme->display( 'RequiresPHP' ),
     666                        'wp_compatible'  => is_wp_version_compatible( $theme->display( 'Requires' ) ),
     667                        'php_compatible' => is_php_version_compatible( $theme->display( 'RequiresPHP' ) ),
     668                        'parent'         => $parent,
     669                        'active'         => $slug === $current_theme,
     670                        'hasUpdate'      => isset( $updates[ $slug ] ),
     671                        'hasPackage'     => isset( $updates[ $slug ] ) && ! empty( $updates[ $slug ]['package'] ),
     672                        'update'         => get_theme_update_available( $theme ),
     673                        'actions'        => array(
    670674                                'activate'  => current_user_can( 'switch_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=activate&stylesheet=' . $encoded_slug ), 'switch-theme_' . $slug ) : null,
    671675                                'customize' => $customize_action,
    672676                                'delete'    => current_user_can( 'delete_themes' ) ? wp_nonce_url( admin_url( 'themes.php?action=delete&stylesheet=' . $encoded_slug ), 'delete-theme_' . $slug ) : null,
  • wp-admin/themes.php

    diff --git a/wp-admin/themes.php b/wp-admin/themes.php
    index 082819611b..272e1d3110 100644
    a b foreach ( $themes as $theme ) : 
    323323
    324324        <?php if ( $theme['hasUpdate'] ) : ?>
    325325                <div class="update-message notice inline notice-warning notice-alt">
    326                 <?php if ( $theme['hasPackage'] ) : ?>
    327                         <p><?php _e( 'New version available. <button class="button-link" type="button">Update now</button>' ); ?></p>
     326                <?php if ( $theme['wp_compatible'] && $theme['php_compatible'] ): ?>
     327                        <?php if ( $theme['hasPackage'] ) : ?>
     328                                <p><?php _e( 'New version available. <button class="button-link" type="button">Update now</button>' ); ?></p>
     329                        <?php else : ?>
     330                                <p><?php _e( 'New version available.' ); ?></p>
     331                        <?php endif; ?>
    328332                <?php else : ?>
    329                         <p><?php _e( 'New version available.' ); ?></p>
     333                        <p><?php _e( 'Version update incompatible.' ); ?></p>
    330334                <?php endif; ?>
    331335                </div>
    332336        <?php endif; ?>
    foreach ( $themes as $theme ) : 
    361365                        /* translators: %s: Theme name. */
    362366                        $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' );
    363367                        ?>
    364                         <a class="button activate" href="<?php echo $theme['actions']['activate']; ?>" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a>
     368                        <?php if ( $theme['wp_compatible'] && $theme['php_compatible'] ): ?>
     369                                <a class="button activate" href="<?php echo $theme['actions']['activate']; ?>" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a>
     370                        <?php else : ?>
     371                                <a class="button disabled" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a>
     372                        <?php endif; ?>
    365373                        <?php if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { ?>
    366374                                <a class="button button-primary load-customize hide-if-no-customize" href="<?php echo $theme['actions']['customize']; ?>"><?php _e( 'Live Preview' ); ?></a>
    367375                        <?php } ?>
    if ( ! is_multisite() && current_user_can( 'edit_themes' ) && $broken_themes ) { 
    491499        <# } #>
    492500
    493501        <# if ( data.hasUpdate ) { #>
    494                 <# if ( data.hasPackage ) { #>
    495                         <div class="update-message notice inline notice-warning notice-alt"><p><?php _e( 'New version available. <button class="button-link" type="button">Update now</button>' ); ?></p></div>
     502                <# if ( data.wp_compatible && data.php_compatible ) { #>
     503                        <div class="update-message notice inline notice-warning notice-alt">
     504                        <# if ( data.hasPackage ) { #>
     505                                <p><?php _e( 'New version available. <button class="button-link" type="button">Update now</button>' ); ?></p></div>
     506                        <# } else { #>
     507                                <div class="update-message notice inline notice-warning notice-alt"><p><?php _e( 'New   version available.' ); ?></p></div>
     508                        <# } #>
    496509                <# } else { #>
    497                         <div class="update-message notice inline notice-warning notice-alt"><p><?php _e( 'New version available.' ); ?></p></div>
     510                        <div class="notice inline notice-warning notice-alt">
     511                        <p><?php _e( 'Update incompatible.' ); ?></p></div>
    498512                <# } #>
    499513        <# } #>
    500514
    if ( ! is_multisite() && current_user_can( 'edit_themes' ) && $broken_themes ) { 
    528542                                /* translators: %s: Theme name. */
    529543                                $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' );
    530544                                ?>
    531                                 <a class="button activate" href="{{{ data.actions.activate }}}" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
     545                                <# if ( data.wp_compatible && data.php_compatible ) { #>
     546                                        <a class="button activate" href="{{{ data.actions.activate }}}" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
     547                                <# } else { #>
     548                                        <a class="button disabled" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
     549                                <# } #>
    532550                                <a class="button button-primary load-customize hide-if-no-customize" href="{{{ data.actions.customize }}}"><?php _e( 'Live Preview' ); ?></a>
    533551                        <# } #>
    534552                </div>
    if ( ! is_multisite() && current_user_can( 'edit_themes' ) && $broken_themes ) { 
    571589
    572590                                <# if ( data.hasUpdate ) { #>
    573591                                <div class="notice notice-warning notice-alt notice-large">
    574                                         <h3 class="notice-title"><?php _e( 'Update Available' ); ?></h3>
    575                                         {{{ data.update }}}
     592                                        <# if ( data.wp_compatible && data.php_compatible ) { #>
     593                                                <h3 class="notice-title"><?php _e( 'Update Available' ); ?></h3>
     594                                                {{{ data.update }}}
     595                                        <# } else { #>
     596                                                <h3 class="notice-title"><?php _e( 'Update incompatible' ); ?></h3>
     597                                                <p><?php printf(
     598                                                                /* translators: %s: WordPress version, %s: PHP version */
     599                                                                __( 'This theme is incompatible with your current installation. This theme requires at least WordPress %s and PHP %s.' ),
     600                                                                '{{{ data.requires }}}',
     601                                                                '{{{ data.requires_php }}}'
     602                                                        ); ?></p>
     603                                        <# } #>
    576604                                </div>
    577605                                <# } #>
    578606                                <p class="theme-description">{{{ data.description }}}</p>
    if ( ! is_multisite() && current_user_can( 'edit_themes' ) && $broken_themes ) { 
    602630                                /* translators: %s: Theme name. */
    603631                                $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' );
    604632                                ?>
    605                                 <# if ( data.actions.activate ) { #>
     633                                <# if ( data.actions.activate && data.wp_compatible && data.php_compatible ) { #>
    606634                                        <a href="{{{ data.actions.activate }}}" class="button activate" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
     635                                <# } else { #>
     636                                        <a class="button disabled" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
    607637                                <# } #>
    608638                                <a href="{{{ data.actions.customize }}}" class="button button-primary load-customize hide-if-no-customize"><?php _e( 'Live Preview' ); ?></a>
    609639                        </div>
  • wp-admin/update-core.php

    diff --git a/wp-admin/update-core.php b/wp-admin/update-core.php
    index e2696ebf62..aad673c84e 100644
    a b function list_theme_updates() { 
    475475        <tbody class="plugins">
    476476        <?php
    477477        foreach ( $themes as $stylesheet => $theme ) {
    478                 $checkbox_id = 'checkbox_' . md5( $theme->get( 'Name' ) );
     478                $checkbox_id    = 'checkbox_' . md5( $theme->get( 'Name' ) );
     479                $compatible_php = is_php_version_compatible( $theme->get( 'RequiresPHP' ) );
     480                $compat         = '';
     481                $annotation     = '';
     482                if ( ! $compatible_php && current_user_can( 'update_php' ) ) {
     483                        $compat .= '<br>' . __( 'This update doesn&#8217;t work with your version of PHP.' ) . '&nbsp;';
     484                        $compat .= sprintf(
     485                                /* translators: %s: URL to Update PHP page. */
     486                                __( '<a href="%s">Learn more about updating PHP</a>.' ),
     487                                esc_url( wp_get_update_php_url() )
     488                        );
     489
     490                        $annotation = wp_get_update_php_annotation();
     491
     492                        if ( $annotation ) {
     493                                $compat .= '</p><p><em>' . $annotation . '</em>';
     494                        }
     495                }
    479496                ?>
    480497        <tr>
    481498                <td class="check-column">
    482                         <input type="checkbox" name="checked[]" id="<?php echo $checkbox_id; ?>" value="<?php echo esc_attr( $stylesheet ); ?>" />
    483                         <label for="<?php echo $checkbox_id; ?>" class="screen-reader-text">
    484                                 <?php
    485                                 /* translators: %s: Theme name. */
    486                                 printf( __( 'Select %s' ), $theme->display( 'Name' ) );
    487                                 ?>
    488                         </label>
     499                        <?php if ( $compatible_php ) : ?>
     500                                <input type="checkbox" name="checked[]" id="<?php echo $checkbox_id; ?>" value="<?php echo esc_attr( $stylesheet ); ?>" />
     501                                <label for="<?php echo $checkbox_id; ?>" class="screen-reader-text">
     502                                        <?php
     503                                        /* translators: %s: Theme name. */
     504                                        printf( __( 'Select %s' ), $theme->display( 'Name' ) );
     505                                        ?>
     506                                </label>
     507                        <?php endif; ?>
    489508                </td>
    490509                <td class="plugin-title"><p>
    491510                        <img src="<?php echo esc_url( $theme->get_screenshot() ); ?>" width="85" height="64" class="updates-table-screenshot" alt="" />
    function list_theme_updates() { 
    497516                                $theme->display( 'Version' ),
    498517                                $theme->update['new_version']
    499518                        );
     519                        echo $compat . $annotation;
    500520                        ?>
    501521                </p></td>
    502522        </tr>
  • wp-includes/class-wp-theme.php

    diff --git a/wp-includes/class-wp-theme.php b/wp-includes/class-wp-theme.php
    index fe8dbb142b..c2e4c1954a 100644
    a b final class WP_Theme implements ArrayAccess { 
    3535                'Tags'        => 'Tags',
    3636                'TextDomain'  => 'Text Domain',
    3737                'DomainPath'  => 'Domain Path',
     38                'Requires'    => 'Requires at least',
     39                'RequiresPHP' => 'Requires PHP',
    3840        );
    3941
    4042        /**
    final class WP_Theme implements ArrayAccess { 
    267269                        );
    268270                        return;
    269271                } else {
    270                         $this->headers = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' );
     272                        $this->headers = $this->get_theme_headers( $theme_dir, $theme_file );
     273
    271274                        // Default themes always trump their pretenders.
    272275                        // Properly identify default themes that are inside a directory within wp-content/themes.
    273276                        $default_theme_slug = array_search( $this->headers['Name'], self::$default_themes );
    final class WP_Theme implements ArrayAccess { 
    850853                                $value = array_filter( array_map( 'trim', explode( ',', strip_tags( $value ) ) ) );
    851854                                break;
    852855                        case 'Version':
     856                        case 'Requires':
     857                        case 'RequiresPHP':
    853858                                $value = strip_tags( $value );
    854859                                break;
    855860                }
    final class WP_Theme implements ArrayAccess { 
    11101115                return $this->theme_root_uri;
    11111116        }
    11121117
     1118        /**
     1119         * Get headers from theme's style.css and readme.txt files.
     1120         *
     1121         * Uses `get_file_data()` to get and combine the theme headers
     1122         * from the theme's style.css and readme.txt files. Then checks
     1123         * the Theme API for WP and PHP compatibility data.
     1124         *
     1125         * Precedence order: API > readme.txt > style.css
     1126         *
     1127         * @since 5.x.x
     1128         *
     1129         * @param string $theme_dir  Directory of the theme within the theme_root.
     1130         * @param string $theme_file Main theme file.
     1131         *
     1132         * @return array Theme headers.
     1133         */
     1134        public function get_theme_headers( $theme_dir, $theme_file ) {
     1135                $theme_headers  = get_file_data( $this->theme_root . '/' . $theme_file, self::$file_headers, 'theme' );
     1136
     1137                $readme = $this->theme_root . '/'. $theme_dir . '/readme.txt';
     1138                if ( file_exists( $readme ) ) {
     1139                        $readme_headers = get_file_data( $readme, self::$file_headers, 'theme' );
     1140
     1141                        // Precedence to headers in readme.txt over style.css file.
     1142                        foreach ( $theme_headers as $header => $value ) {
     1143                                if ( ! empty( $readme_headers[ $header ] ) ) {
     1144                                        $theme_headers[ $header ] = $readme_headers[ $header ];
     1145                                }
     1146                        }
     1147                }
     1148
     1149                // Get Theme API data.
     1150                $response = wp_remote_get( "https://api.wordpress.org/themes/info/1.2/?action=theme_information&request[slug]=$theme_dir" );
     1151                $response = wp_remote_retrieve_body( $response );
     1152                $response = json_decode( $response );
     1153
     1154                if ( ! property_exists( $response, 'error' ) ) {
     1155                        // Precedence to Theme API.
     1156                        $theme_headers['Requires']    = ! empty( $response->requires ) ? $response->requires : $theme_headers['Requires'];
     1157                        $theme_headers['RequiresPHP'] = ! empty( $response->requires ) ? $response->requires_php : $theme_headers['RequiresPHP'];
     1158                }
     1159
     1160                return $theme_headers;
     1161        }
     1162
    11131163        /**
    11141164         * Returns the main screenshot file for the theme.
    11151165         *