WordPress.org

Make WordPress Core

Ticket #26909: 0001-add-plugin-headers-Core-PHP-and-functions-to-check-a.patch

File 0001-add-plugin-headers-Core-PHP-and-functions-to-check-a.patch, 14.5 KB (added by cfoellmann, 8 years ago)
  • wp-admin/css/colors.css

    From 54c3b8dfbd9f410bbedfa9592073d5579815e5f8 Mon Sep 17 00:00:00 2001
    From: Christian Foellmann <foellmann@foe-services.de>
    Date: Mon, 23 Dec 2013 01:07:53 +0100
    Subject: [PATCH] add plugin headers 'Core', 'PHP' and functions to check
     against environment variables
    
    ---
     wp-admin/css/colors.css                           |   5 +-
     wp-admin/includes/class-wp-plugins-list-table.php |  74 ++++++++++++---
     wp-admin/includes/plugin.php                      | 106 +++++++++++++++++++++-
     3 files changed, 169 insertions(+), 16 deletions(-)
    
    diff --git a/wp-admin/css/colors.css b/wp-admin/css/colors.css
    index f26c716..522964f 100644
    a b tr.active + tr.plugin-update-tr .plugin-update { 
    824824.plugins .active.update td,
    825825.plugins .active.update th,
    826826tr.active.update + tr.plugin-update-tr .plugin-update,
     827.plugins .inactive.incompatible td,
     828.plugins .inactive.incompatible th,
    827829#activity-widget #the-comment-list .unapproved {
    828830        background-color: #fefaf7;
    829831}
    tr.active.update + tr.plugin-update-tr .plugin-update, 
    849851}
    850852
    851853.plugins .active.update th.check-column,
    852 .plugins .active.update + .plugin-update-tr .plugin-update {
     854.plugins .active.update + .plugin-update-tr .plugin-update,
     855.plugins .inactive.incompatible th.check-column {
    853856        border-left: 4px solid #d54e21;
    854857}
    855858
  • wp-admin/includes/class-wp-plugins-list-table.php

    diff --git a/wp-admin/includes/class-wp-plugins-list-table.php b/wp-admin/includes/class-wp-plugins-list-table.php
    index 9e64849..1230fb3 100644
    a b class WP_Plugins_List_Table extends WP_List_Table { 
    1818                ) );
    1919
    2020                $status = 'all';
    21                 if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'active', 'inactive', 'recently_activated', 'upgrade', 'mustuse', 'dropins', 'search' ) ) )
     21                if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'active', 'inactive', 'recently_activated', 'upgrade', 'mustuse', 'dropins', 'search', 'incompatible' ) ) ) {
    2222                        $status = $_REQUEST['plugin_status'];
     23                }
    2324
    2425                if ( isset($_REQUEST['s']) )
    2526                        $_SERVER['REQUEST_URI'] = add_query_arg('s', wp_unslash($_REQUEST['s']) );
    class WP_Plugins_List_Table extends WP_List_Table { 
    4849                        'recently_activated' => array(),
    4950                        'upgrade' => array(),
    5051                        'mustuse' => array(),
    51                         'dropins' => array()
     52                        'dropins' => array(),
     53                        'incompatible' => array(),
    5254                );
    5355
    5456                $screen = $this->screen;
    class WP_Plugins_List_Table extends WP_List_Table { 
    5860                                $plugins['mustuse'] = get_mu_plugins();
    5961                        if ( apply_filters( 'show_advanced_plugins', true, 'dropins' ) )
    6062                                $plugins['dropins'] = get_dropins();
    61 
     63                        if ( apply_filters( 'show_advanced_plugins', true, 'incompatible' ) ) {
     64                                $plugins['incompatible'] = get_incompatible_plugins();
     65                        }
     66                       
    6267                        if ( current_user_can( 'update_plugins' ) ) {
    6368                                $current = get_site_transient( 'update_plugins' );
    6469                                foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
    class WP_Plugins_List_Table extends WP_List_Table { 
    6873                                        }
    6974                                }
    7075                        }
     76                } elseif ( is_multisite() && !is_network_admin() && current_user_can( 'manage_network_plugins' ) ) {
     77                        if ( apply_filters( 'show_advanced_plugins', true, 'incompatible' ) ) {
     78                                $plugins['incompatible'] = get_incompatible_plugins();
     79                        }
    7180                }
    7281
    7382                set_transient( 'plugin_slugs', array_keys( $plugins['all'] ), DAY_IN_SECONDS );
    class WP_Plugins_List_Table extends WP_List_Table { 
    8796                                unset( $plugins['all'][ $plugin_file ] );
    8897                        } elseif ( ! $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) {
    8998                                unset( $plugins['all'][ $plugin_file ] );
    90                         } elseif ( ( ! $screen->in_admin( 'network' ) && is_plugin_active( $plugin_file ) )
    91                                 || ( $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) ) {
     99                        } elseif ( !is_plugin_compatible( $plugin_file ) ) {
     100                                unset( $plugins['all'][ $plugin_file ] );
     101                        } elseif ( ( ! $screen->in_admin( 'network' ) && is_plugin_active( $plugin_file ) )     || ( $screen->in_admin( 'network' ) && is_plugin_active_for_network( $plugin_file ) ) ) {
    92102                                $plugins['active'][ $plugin_file ] = $plugin_data;
    93103                        } else {
    94                                 if ( ! $screen->in_admin( 'network' ) && isset( $recently_activated[ $plugin_file ] ) ) // Was the plugin recently activated?
     104                                if ( ! $screen->in_admin( 'network' ) && isset( $recently_activated[ $plugin_file ] ) ) {// Was the plugin recently activated?
    95105                                        $plugins['recently_activated'][ $plugin_file ] = $plugin_data;
     106                                }
    96107                                $plugins['inactive'][ $plugin_file ] = $plugin_data;
    97108                        }
    98109                }
    class WP_Plugins_List_Table extends WP_List_Table { 
    177188                global $status;
    178189
    179190                return array(
    180                         'cb'          => !in_array( $status, array( 'mustuse', 'dropins' ) ) ? '<input type="checkbox" />' : '',
     191                        'cb'          => !in_array( $status, array( 'mustuse', 'dropins' ) ) || !( 'incompatible' == $status && is_multisite() && is_network_admin() ) ? '<input type="checkbox" />' : '',
    181192                        'name'        => __( 'Plugin' ),
    182193                        'description' => __( 'Description' ),
    183194                );
    class WP_Plugins_List_Table extends WP_List_Table { 
    208219                                case 'inactive':
    209220                                        $text = _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', $count );
    210221                                        break;
     222                                case 'incompatible':
     223                                        $text = _n( 'Incompatible <span class="count">(%s)</span>', 'Incompatible <span class="count">(%s)</span>', $count );
     224                                        break;
    211225                                case 'mustuse':
    212226                                        $text = _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', $count );
    213227                                        break;
    class WP_Plugins_List_Table extends WP_List_Table { 
    235249                global $status;
    236250
    237251                $actions = array();
     252               
     253                if ( 'incompatible' == $status ) {
     254                        if ( is_multisite() ) {
     255                                if ( is_network_admin() && current_user_can( 'manage_network_plugins' ) ) {
     256                                        $actions['delete-selected'] = __( 'Delete' );
     257                                        $actions['update-selected'] = __( 'Update' );
     258                                        return $actions;
     259                                } else {
     260                                        return $actions;
     261                                }
     262                        } else {
     263                                if ( current_user_can( 'update_plugins' ) ) {
     264                                        $actions['update-selected'] = __( 'Update' );
     265                                }
     266                                if ( current_user_can( 'delete_plugins' ) && ( 'active' != $status ) ) {
     267                                        $actions['delete-selected'] = __( 'Delete' );
     268                                }
     269                                return $actions;
     270                        }
     271                }
    238272
    239273                if ( 'active' != $status )
    240274                        $actions['activate-selected'] = $this->screen->in_admin( 'network' ) ? __( 'Network Activate' ) : __( 'Activate' );
    241275
    242276                if ( 'inactive' != $status && 'recent' != $status )
    243277                        $actions['deactivate-selected'] = $this->screen->in_admin( 'network' ) ? __( 'Network Deactivate' ) : __( 'Deactivate' );
    244 
     278               
    245279                if ( !is_multisite() || $this->screen->in_admin( 'network' ) ) {
    246280                        if ( current_user_can( 'update_plugins' ) )
    247281                                $actions['update-selected'] = __( 'Update' );
    class WP_Plugins_List_Table extends WP_List_Table { 
    262296        }
    263297
    264298        function extra_tablenav( $which ) {
    265                 global $status;
     299                global $status, $wp_version;
    266300
    267                 if ( ! in_array($status, array('recently_activated', 'mustuse', 'dropins') ) )
     301                if ( ! in_array( $status, array( 'recently_activated', 'mustuse', 'dropins', 'incompatible' ) ) )
    268302                        return;
    269303
    270304                echo '<div class="alignleft actions">';
    271 
     305               
    272306                if ( ! $this->screen->in_admin( 'network' ) && 'recently_activated' == $status )
    273307                        submit_button( __( 'Clear List' ), 'button', 'clear-recent-list', false );
    274308                elseif ( 'top' == $which && 'mustuse' == $status )
    275309                        echo '<p>' . sprintf( __( 'Files in the <code>%s</code> directory are executed automatically.' ), str_replace( ABSPATH, '/', WPMU_PLUGIN_DIR ) ) . '</p>';
    276310                elseif ( 'top' == $which && 'dropins' == $status )
    277311                        echo '<p>' . sprintf( __( 'Drop-ins are advanced plugins in the <code>%s</code> directory that replace WordPress functionality when present.' ), str_replace( ABSPATH, '', WP_CONTENT_DIR ) ) . '</p>';
    278 
     312                elseif ( 'bottom' == $which && 'incompatible' == $status ) {
     313                        if ( is_multisite() && is_network_admin() && current_user_can( 'manage_network' ) || !is_multisite() && current_user_can( 'install_plugins' ) ) {
     314                                echo '<p> Your PHP version is: ' . PHP_VERSION . ' | Your WP version is: ' . $wp_version . '</p>'; //@todo
     315                        }
     316                }
    279317                echo '</div>';
    280318        }
    281319
    class WP_Plugins_List_Table extends WP_List_Table { 
    330368                        }
    331369                        if ( $plugin_data['Description'] )
    332370                                $description .= '<p>' . $plugin_data['Description'] . '</p>';
     371                } elseif ( 'incompatible' == $context ) {
     372                        $is_active = false;
     373                        if ( is_network_admin() && current_user_can( 'manage_network_plugins' ) ) {
     374                                $actions['delete'] = '<a href="' . wp_nonce_url('plugins.php?action=delete-selected&amp;checked[]=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins') . '" title="' . esc_attr__( 'Delete this plugin' ) . '" class="delete">' . __( 'Delete' ) . '</a>';
     375                        } elseif ( !is_multisite() && current_user_can( 'delete_plugins' ) ) {
     376                                $actions['delete'] = '<a href="' . wp_nonce_url('plugins.php?action=delete-selected&amp;checked[]=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'bulk-plugins') . '" title="' . esc_attr__( 'Delete this plugin' ) . '" class="delete">' . __( 'Delete' ) . '</a>';
     377                        }
    333378                } else {
    334379                        if ( $screen->in_admin( 'network' ) )
    335380                                $is_active = is_plugin_active_for_network( $plugin_file );
    class WP_Plugins_List_Table extends WP_List_Table { 
    367412
    368413                $class = $is_active ? 'active' : 'inactive';
    369414                $checkbox_id =  "checkbox_" . md5($plugin_data['Name']);
    370                 if ( in_array( $status, array( 'mustuse', 'dropins' ) ) ) {
     415                if ( in_array( $status, array( 'mustuse', 'dropins' ) ) || 'incompatible' == $context ) {
    371416                        $checkbox = '';
     417                        $class .= ' incompatible';
    372418                } else {
    373419                        $checkbox = "<label class='screen-reader-text' for='" . $checkbox_id . "' >" . sprintf( __( 'Select %s' ), $plugin_data['Name'] ) . "</label>"
    374420                                . "<input type='checkbox' name='checked[]' value='" . esc_attr( $plugin_file ) . "' id='" . $checkbox_id . "' />";
    class WP_Plugins_List_Table extends WP_List_Table { 
    430476                }
    431477
    432478                echo "</tr>";
    433 
     479               
    434480                do_action( 'after_plugin_row', $plugin_file, $plugin_data, $status );
    435481                do_action( "after_plugin_row_$plugin_file", $plugin_file, $plugin_data, $status );
    436482        }
  • wp-admin/includes/plugin.php

    diff --git a/wp-admin/includes/plugin.php b/wp-admin/includes/plugin.php
    index e85ac5b..f423676 100644
    a b  
    4747 *              'TextDomain' - Plugin's text domain for localization.
    4848 *              'DomainPath' - Plugin's relative directory path to .mo files.
    4949 *              'Network' - Boolean. Whether the plugin can only be activated network wide.
     50 *              'Core' - The minimum WordPress version required.
     51 *              'PHP' - The minimal PHP version required.
    5052 *
    5153 * Some users have issues with opening large files and manipulating the contents
    5254 * for want is usually the first 1kiB or 2kiB. This function stops pulling in
    function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { 
    8385                'Network' => 'Network',
    8486                // Site Wide Only is deprecated in favor of Network.
    8587                '_sitewide' => 'Site Wide Only',
     88                'Core' => 'Core',
     89                'PHP' => 'PHP',
    8690        );
    8791
    8892        $plugin_data = get_file_data( $plugin_file, $default_headers, 'plugin' );
    function get_plugin_data( $plugin_file, $markup = true, $translate = true ) { 
    9498        }
    9599        $plugin_data['Network'] = ( 'true' == strtolower( $plugin_data['Network'] ) );
    96100        unset( $plugin_data['_sitewide'] );
    97 
     101       
    98102        if ( $markup || $translate ) {
    99103                $plugin_data = _get_plugin_data_markup_translate( $plugin_file, $plugin_data, $markup, $translate );
    100104        } else {
    function get_mu_plugins() { 
    346350}
    347351
    348352/**
     353 * @todo
     354 *
     355 * @todo
     356 *
     357 * @since 3.9.0
     358 * @return array @todo Key is the mu-plugin file path and the value is an array of the mu-plugin data.
     359 */
     360function get_incompatible_plugins() {
     361        $incompatible_plugins = array();
     362        $wp_plugins = get_plugins();
     363       
     364        foreach ( $wp_plugins as $plugin => $plugin_data ) {
     365                if ( is_plugin_incompatible( $plugin ) ) {
     366                        $incompatible_plugins[ $plugin ] = $plugin_data;
     367                }
     368        }
     369
     370        uasort( $incompatible_plugins, '_sort_uname_callback' );
     371        return $incompatible_plugins;
     372}
     373
     374/**
    349375 * Callback to sort array by a 'Name' key.
    350376 *
    351377 * @since 3.1.0
    function is_plugin_inactive( $plugin ) { 
    454480}
    455481
    456482/**
     483 * Check whether the plugin is compatible to current environment.
     484 *
     485 * Prevent activation if required WP core version or PHP version is not met or
     486 * plugin is incompatible to network wide activation.
     487 *
     488 * @since 3.9.0
     489 *
     490 * @global int $wp_version The current version of this particular WP instance
     491 *
     492 * @param string $plugin Base plugin path from plugins directory.
     493 * @return bool True if compatible. False if incompatible.
     494 */
     495function is_plugin_compatible( $plugin ) {
     496       
     497        $plugin_file = WP_PLUGIN_DIR . '/' . $plugin;
     498               
     499        if ( is_plugin_compatible_to_php( $plugin_file ) && is_plugin_compatible_to_core( $plugin_file ) ) {   
     500                return true;
     501        } else {
     502                return false;
     503        }
     504       
     505}
     506
     507/**
     508 * @todo
     509 *
     510 * Reverse of iis_plugin_compatible(). Used as a callback.
     511 *
     512 * @since 3.9.0
     513 *
     514 * @param string $plugin Base plugin path from plugins directory.
     515 * @return bool True if incompatible. False if compatible.
     516 */
     517function is_plugin_incompatible( $plugin ) {
     518        return !is_plugin_compatible( $plugin );
     519}
     520
     521/**
     522 * Check whether the plugin is compatible to the current PHP version.
     523 *
     524 * @since 3.9.0
     525 *
     526 * @param string $plugin Base plugin path from plugins directory.
     527 * @return bool True if compatible. False if incompatible.
     528 */
     529function is_plugin_compatible_to_php( $plugin ) {
     530        $plugin_data = get_plugin_data( $plugin );
     531       
     532        if ( isset( $plugin_data['PHP'] ) ) {
     533                return version_compare( PHP_VERSION, $plugin_data['PHP'], '>=' );
     534        } else {
     535                return true;
     536        }
     537}
     538
     539/**
     540 * Check whether the plugin is compatible to the current WP version.
     541 *
     542 * @since 3.9.0
     543 *
     544 * @global int $wp_version The current version of this particular WP instance
     545 *
     546 * @param string $plugin Base plugin path from plugins directory.
     547 * @return bool True if compatible. False if incompatible.
     548 */
     549function is_plugin_compatible_to_core( $plugin ) {
     550        $plugin_data = get_plugin_data( $plugin );
     551       
     552        if ( isset( $plugin_data['Core'] ) ) {
     553                global $wp_version;
     554                return version_compare( $wp_version, $plugin_data['Core'], '>=' );
     555        } else {
     556                return true;
     557        }
     558}
     559
     560/**
    457561 * Check whether the plugin is active for the entire network.
    458562 *
    459563 * @since 3.0.0