WordPress.org

Make WordPress Core

Ticket #24205: 0001-Patch-for-issue-24205-is_plugin_active-should-return.patch

File 0001-Patch-for-issue-24205-is_plugin_active-should-return.patch, 9.4 KB (added by jrf, 5 years ago)
  • src/wp-admin/includes/plugin.php

    From ae344441b95d734314a0427dcca1be795d234858 Mon Sep 17 00:00:00 2001
    From: jrf <wordpress_nospam@adviesenzo.nl>
    Date: Mon, 20 Apr 2015 12:55:14 +0200
    Subject: [PATCH] Patch for issue #24205 - is_plugin_active() should return
     true for must-use/dropin plugins
    
    Based on @rcoll's patch for the same - https://core.trac.wordpress.org/attachment/ticket/24205/24205.patch
    
    Improvements:
    - Use the more efficient wp_get_mu_plugins() function instead of get_mu_plugins()
    - Allow for bootstrapped MU plugins
    - Added relevant unit tests
    - Made the wp_get_mu_plugins() function slightly more efficient as reading directories is expensive and the function might now be called several times
    - Made the touched functions comply with code style guidelines
    - Checked all core uses of the touched functions
    
    What I didn't do:
    - Add unit tests for the network version as that would involve duplicating the `_back_up_drop_ins()`, `_restore_drop_ins()`, `_back_up_mu_plugins()` and `_restore_mu_plugins()` methods from the `Tests_Admin_includesPlugin` class to the `Tests_Multisite_Network` class or moving these methods elsewhere (to the `WP_UnitTestCase` class would seem a logical place)
    ---
     src/wp-admin/includes/plugin.php             | 83 +++++++++++++++++++++++-----
     src/wp-includes/load.php                     | 27 +++++----
     tests/phpunit/tests/admin/includesPlugin.php | 79 ++++++++++++++++++++++++++
     3 files changed, 166 insertions(+), 23 deletions(-)
    
    diff --git a/src/wp-admin/includes/plugin.php b/src/wp-admin/includes/plugin.php
    index bb16117..6b2ca41 100644
    a b function _get_dropins() { 
    431431 *
    432432 * @since 2.5.0
    433433 *
    434  * @param string $plugin Base plugin path from plugins directory.
    435  * @return bool True, if in the active plugins list. False, not in the list.
     434 * @param string $plugin    Base plugin path from plugins directory.
     435 * @param bool   $check_all Defaults false. On true, checks mu-plugins and dropins for existence.
     436 * @return bool  True, if in the active plugins list. False, not in the list.
    436437 */
    437 function is_plugin_active( $plugin ) {
    438         return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
     438function is_plugin_active( $plugin, $check_all = false ) {
     439        if ( in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin, $check_all ) ) {
     440                return true;
     441        }
     442
     443        if ( $check_all ) {
     444                if ( _is_mustuse_plugin( $plugin ) === true || _is_dropin_plugin( $plugin ) === true ) {
     445                        return true;
     446                }
     447        }
     448
     449        return false;
    439450}
    440451
    441452/**
    function is_plugin_active( $plugin ) { 
    446457 * @since 3.1.0
    447458 * @see is_plugin_active()
    448459 *
    449  * @param string $plugin Base plugin path from plugins directory.
    450  * @return bool True if inactive. False if active.
     460 * @param string $plugin    Base plugin path from plugins directory.
     461 * @param bool   $check_all Defaults false. On true, checks mu-plugins and dropins for existence.
     462 * @return bool  True if inactive. False if active.
    451463 */
    452 function is_plugin_inactive( $plugin ) {
    453         return ! is_plugin_active( $plugin );
     464function is_plugin_inactive( $plugin, $check_all = false ) {
     465        return ! is_plugin_active( $plugin, $check_all );
    454466}
    455467
    456468/**
    function is_plugin_inactive( $plugin ) { 
    458470 *
    459471 * @since 3.0.0
    460472 *
    461  * @param string $plugin Base plugin path from plugins directory.
    462  * @return bool True, if active for the network, otherwise false.
     473 * @param string $plugin    Base plugin path from plugins directory.
     474 * @param bool   $check_all Defaults false. On true, checks mu-plugins and dropins for existence.
     475 * @return bool  True, if active for the network, otherwise false.
    463476 */
    464 function is_plugin_active_for_network( $plugin ) {
    465         if ( !is_multisite() )
     477function is_plugin_active_for_network( $plugin, $check_all = false ) {
     478        if ( !is_multisite() ) {
    466479                return false;
     480        }
    467481
    468482        $plugins = get_site_option( 'active_sitewide_plugins');
    469         if ( isset($plugins[$plugin]) )
     483        if ( isset($plugins[$plugin]) ) {
     484                return true;
     485        }
     486
     487        if ( $check_all ) {
     488                if ( _is_mustuse_plugin( $plugin ) === true || _is_dropin_plugin( $plugin ) === true ) {
     489                        return true;
     490                }
     491        }
     492
     493        return false;
     494}
     495
     496/**
     497 * Check whether the plugin is a must-use plugin.
     498 *
     499 * @since 4.x.x
     500 *
     501 * @param string $plugin    Base plugin path.
     502 * @return bool  True, if must-use plugin, otherwise false.
     503 */
     504function _is_mustuse_plugin( $plugin ) {
     505        $mu_plugins = wp_get_mu_plugins();
     506        if ( in_array( WPMU_PLUGIN_DIR . '/' . $plugin, $mu_plugins, true ) ) {
     507                return true;
     508        }
     509        // Also test for bootstrap file with same name as main plugin file
     510        if ( strpos( $plugin, '/' ) && in_array( WPMU_PLUGIN_DIR . '/' . basename( $plugin ), $mu_plugins, true ) ) {
    470511                return true;
     512        }
     513        return false;
     514}
    471515
     516/**
     517 * Check whether the plugin is a drop-in plugin.
     518 *
     519 * @since 4.x.x
     520 *
     521 * @param string $plugin    Base plugin path.
     522 * @return bool  True, if drop-in plugin, otherwise false.
     523 */
     524function _is_dropin_plugin( $plugin ) {
     525        $dropins = get_dropins();
     526        if ( array_key_exists( $plugin, $dropins ) ) {
     527                return true;
     528        }
    472529        return false;
    473530}
    474531
  • src/wp-includes/load.php

    diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php
    index b41e650..4bbec2a 100644
    a b function wp_not_installed() { 
    498498 * @return array Files to include.
    499499 */
    500500function wp_get_mu_plugins() {
    501         $mu_plugins = array();
    502         if ( !is_dir( WPMU_PLUGIN_DIR ) )
    503                 return $mu_plugins;
    504         if ( ! $dh = opendir( WPMU_PLUGIN_DIR ) )
    505                 return $mu_plugins;
    506         while ( ( $plugin = readdir( $dh ) ) !== false ) {
    507                 if ( substr( $plugin, -4 ) == '.php' )
    508                         $mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin;
     501        static $mu_plugins;
     502       
     503        if ( ! isset( $mu_plugins ) ) {
     504                $mu_plugins = array();
     505                if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
     506                        return $mu_plugins;
     507                }
     508                if ( ! $dh = opendir( WPMU_PLUGIN_DIR ) ) {
     509                        return $mu_plugins;
     510                }
     511                while ( ( $plugin = readdir( $dh ) ) !== false ) {
     512                        if ( substr( $plugin, -4 ) == '.php' ) {
     513                                $mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin;
     514                        }
     515                }
     516                closedir( $dh );
     517                sort( $mu_plugins );
    509518        }
    510         closedir( $dh );
    511         sort( $mu_plugins );
    512519
    513520        return $mu_plugins;
    514521}
  • tests/phpunit/tests/admin/includesPlugin.php

    diff --git a/tests/phpunit/tests/admin/includesPlugin.php b/tests/phpunit/tests/admin/includesPlugin.php
    index 15afaef..493902f 100644
    a b class Tests_Admin_includesPlugin extends WP_UnitTestCase { 
    5757                wp_set_current_user( $current_user );
    5858        }
    5959
     60        /**
     61         * @covers ::is_plugin_active
     62         */
    6063        function test_is_plugin_active_true() {
    6164                activate_plugin( 'hello.php' );
    6265                $test = is_plugin_active( 'hello.php' );
    class Tests_Admin_includesPlugin extends WP_UnitTestCase { 
    6568                deactivate_plugins( 'hello.php' );
    6669        }
    6770
     71        /**
     72         * @covers ::is_plugin_active
     73         */
    6874        function test_is_plugin_active_false() {
    6975                deactivate_plugins( 'hello.php' );
    7076                $test = is_plugin_active( 'hello.php' );
    7177                $this->assertFalse( $test );
    7278        }
    7379
     80        /**
     81         * @covers ::is_plugin_inactive
     82         */
    7483        function test_is_plugin_inactive_true() {
    7584                deactivate_plugins( 'hello.php' );
    7685                $test = is_plugin_inactive( 'hello.php' );
    7786                $this->assertTrue( $test );
    7887        }
    7988
     89        /**
     90         * @covers ::is_plugin_inactive
     91         */
    8092        function test_is_plugin_inactive_false() {
    8193                activate_plugin( 'hello.php' );
    8294                $test = is_plugin_inactive( 'hello.php' );
    class Tests_Admin_includesPlugin extends WP_UnitTestCase { 
    8698        }
    8799
    88100        /**
     101         * @covers ::is_plugin_active
     102         */
     103        function test_is_plugin_active_dropin_true() {
     104                $this->_back_up_drop_ins();
     105
     106                $p1 = $this->_create_plugin( "<?php\n//Test", 'db.php', WP_CONTENT_DIR );
     107
     108                $test = is_plugin_active( 'db.php', true );
     109                $this->assertTrue( $test );
     110
     111                // Clean up.
     112                unlink( $p1[1] );
     113                $this->_restore_drop_ins();
     114        }
     115
     116        /**
     117         * @covers ::is_plugin_active
     118         */
     119        function test_is_plugin_active_mustuse_true() {
     120                if ( is_dir( WPMU_PLUGIN_DIR ) ) {
     121                        $exists = true;
     122                        $this->_back_up_mu_plugins();
     123                } else {
     124                        $exists = false;
     125                        mkdir( WPMU_PLUGIN_DIR );
     126                }
     127                copy( DIR_TESTDATA . '/plugins/hello.php', WPMU_PLUGIN_DIR . '/hello.php' );
     128
     129                $test = is_plugin_active( 'hello.php', true );
     130                $this->assertTrue( $test );
     131
     132                // Clean up.
     133                unlink( WPMU_PLUGIN_DIR . '/hello.php' );
     134                if ( $exists ) {
     135                        $this->_restore_mu_plugins();
     136                } else {
     137                        rmdir( WPMU_PLUGIN_DIR );
     138                }
     139        }
     140
     141        /**
     142         * @covers ::is_plugin_active
     143         */
     144        function test_is_plugin_active_mustuse_bootstrap_true() {
     145                if ( is_dir( WPMU_PLUGIN_DIR ) ) {
     146                        $exists = true;
     147                        $this->_back_up_mu_plugins();
     148                } else {
     149                        $exists = false;
     150                        mkdir( WPMU_PLUGIN_DIR );
     151                }
     152                copy( DIR_TESTDATA . '/plugins/hello.php', WPMU_PLUGIN_DIR . '/hello.php' );
     153
     154                $test = is_plugin_active( 'hello/hello.php', true );
     155                $this->assertTrue( $test );
     156
     157                // Clean up.
     158                unlink( WPMU_PLUGIN_DIR . '/hello.php' );
     159                if ( $exists ) {
     160                        $this->_restore_mu_plugins();
     161                } else {
     162                        rmdir( WPMU_PLUGIN_DIR );
     163                }
     164        }
     165
     166
     167        /**
    89168         * @covers ::get_plugin_files
    90169         */
    91170        public function test_get_plugin_files_single() {