Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion includes/Checker/Abstract_Check_Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,17 @@ abstract protected function get_check_slugs_to_run();
public function prepare() {
if ( $this->requires_universal_preparations( $this->get_checks_to_run() ) ) {
$preparation = new Universal_Runtime_Preparation( $this->get_checks_instance()->context() );
return $preparation->prepare();
$cleanup = $preparation->prepare();

// Set the database prefix to use the demo tables.
global $wpdb;
$old_prefix = $wpdb->set_prefix( 'wppc_' );

return function() use ( $old_prefix, $cleanup ) {
global $wpdb;
$wpdb->set_prefix( $old_prefix );
$cleanup();
};
}

return function() {};
Expand Down
97 changes: 97 additions & 0 deletions includes/Checker/Runtime_Environment_Setup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* Class WordPress\Plugin_Check\Checker\Runtime_Environment_Setup
*
* @package plugin-check
*/

namespace WordPress\Plugin_Check\Checker;

/**
* Class to setup the Runtime Environment for Runtime checks.
*
* @since n.e.x.t
*/
class Runtime_Environment_Setup {

/**
* Sets up the WordPress environment for runtime checks
*
* @since n.e.x.t
*/
public function setup() {
global $wpdb, $wp_filesystem;

require_once ABSPATH . '/wp-admin/includes/upgrade.php';

// Set the new prefix.
$old_prefix = $wpdb->set_prefix( 'wppc_' );

// Create and populate the test database tables if they do not exist.
if ( 'wppc_posts' !== $wpdb->get_var( "SHOW TABLES LIKE 'wppc_posts'" ) ) {
wp_install(
'Plugin Check',
'plugincheck',
'demo@plugincheck.test',
false
);
}

// Restore the old prefix.
$wpdb->set_prefix( $old_prefix );

// Return early if the plugin check object cache already exists.
if ( defined( 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION' ) && WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION ) {
Comment thread
joemcgill marked this conversation as resolved.
return;
}

// Create the object-cache.php file.
if ( $wp_filesystem || WP_Filesystem() ) {
Comment thread
jjgrainger marked this conversation as resolved.
// Do not replace the object-cache.php file if it already exists.
if ( ! $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
$wp_filesystem->copy( WP_PLUGIN_CHECK_PLUGIN_DIR_PATH . 'object-cache.copy.php', WP_CONTENT_DIR . '/object-cache.php' );
}
}
}

/**
* Cleans up the runtime environment setup.
*
* @since n.e.x.t
*/
public function cleanup() {
global $wpdb, $wp_filesystem;

require_once ABSPATH . '/wp-admin/includes/upgrade.php';

$old_prefix = $wpdb->set_prefix( 'wppc_' );
$tables = $wpdb->tables();

foreach ( $tables as $table ) {
$wpdb->query( "DROP TABLE IF EXISTS `$table`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}

// Restore the old prefix.
$wpdb->set_prefix( $old_prefix );

// Return early if the plugin check object cache does not exist.
if ( ! defined( 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION' ) || ! WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION ) {
return;
}

// Remove the object-cache.php file.
if ( $wp_filesystem || WP_Filesystem() ) {
Comment thread
jjgrainger marked this conversation as resolved.
if ( ! $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
return;
}

// Check the drop-in file matches the copy.
$original_content = $wp_filesystem->get_contents( WP_CONTENT_DIR . '/object-cache.php' );
$copy_content = $wp_filesystem->get_contents( WP_PLUGIN_CHECK_PLUGIN_DIR_PATH . 'object-cache.copy.php' );

if ( $original_content && $original_content === $copy_content ) {
$wp_filesystem->delete( WP_CONTENT_DIR . '/object-cache.php' );
}
}
}
}
54 changes: 54 additions & 0 deletions includes/Utilities/Plugin_Request_Utility.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace WordPress\Plugin_Check\Utilities;

use Exception;
use WordPress\Plugin_Check\Checker\CLI_Runner;
use WordPress\Plugin_Check\Checker\AJAX_Runner;

/**
* Class providing utility methods to return plugin information based on the request.
Expand All @@ -16,6 +18,22 @@
*/
class Plugin_Request_Utility {

/**
* Instance of the current runner based on the request.
*
* @since n.e.x.t
* @var Abstract_Check_Runner
*/
protected static $runner;

/**
* The universal runtime preparation cleanups if applied.
*
* @since n.e.x.t
* @var callable
*/
protected static $cleanup;

/**
* Returns the plugin basename based on the input provided.
*
Expand Down Expand Up @@ -60,4 +78,40 @@ public static function get_plugin_basename_from_input( $plugin_slug ) {
)
);
}

/**
* Initializes the runner classes.
*
* @since n.e.x.t
*/
public static function initialize_runner() {
$runners = array(
new CLI_Runner(),
new AJAX_Runner(),
);

foreach ( $runners as $runner ) {
if ( $runner->is_plugin_check() ) {
// @TODO: Handle the cleanup function in later issue with shutdown action or method that returns cleanup functions.
static::$cleanup = $runner->prepare();
Comment thread
felixarntz marked this conversation as resolved.
Comment thread
jjgrainger marked this conversation as resolved.
static::$runner = $runner;
break;
}
}
}

/**
* Get the Runner class for the current request.
*
* @since n.e.x.t
*
* @return Abstract_Check_Runner|null The Runner class for the request or null.
*/
public static function get_runner() {
if ( isset( static::$runner ) ) {
return static::$runner;
}

return null;
}
}
43 changes: 43 additions & 0 deletions object-cache.copy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

<?php
/**
* Plugin Name: Plugin Check Object Cache Drop-In
* Plugin URI: https://github.com/WordPress/plugin-check
* Description: Plugin check drop-in to setup the test environment early. This is not a real object cache drop-in and will not override other actual object cache drop-ins.
* Version: 1
* Author: WordPress Performance Team
* Author URI: https://make.wordpress.org/performance/
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Object cache drop-in from Plugin Check.
*
* This drop-in is used, admittedly as a hack, to be able to setup the
* WordPress environment as early as possible. Once a plugin is loaded, it is
* too late to configure the test environment.
*
* This file respects any real object cache implementation the site may already
* be using, and it is implemented in a way that there is no risk for breakage.
*
* @package plugin-check
* @since n.e.x.t
*/

// Set constant to be able to later check for whether this file was loaded.
define( 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION', 1 );

function plugin_check_initialize_runner() {
$plugins_dir = defined( 'WP_PLUGIN_DIR' ) ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/plugins';
$plugin_dir = $plugins_dir . '/plugin-check/';
if ( ! file_exists( $plugin_dir . 'vendor/autoload.php' ) ) {
return;
}

require_once $plugin_dir . 'vendor/autoload.php';

if ( class_exists( 'WordPress\Plugin_Check\Utilities\Plugin_Request_Utility' ) ) {
// Initialize the Check Runner class based on the request.
WordPress\Plugin_Check\Utilities\Plugin_Request_Utility::initialize_runner();
}
}
plugin_check_initialize_runner();
7 changes: 7 additions & 0 deletions tests/Checker/AJAX_Runner_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

class AJAX_Runner_Tests extends WP_UnitTestCase {

public function tear_down() {
// Force reset the database prefix after runner prepare method called.
global $wpdb, $table_prefix;
$wpdb->set_prefix( $table_prefix );
parent::tear_down();
}

public function test_is_plugin_check_returns_true() {
// Mock the AJAX request.
add_filter( 'wp_doing_ajax', '__return_true' );
Expand Down
7 changes: 7 additions & 0 deletions tests/Checker/CLI_Runner_Tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

class CLI_Runner_Tests extends WP_UnitTestCase {

public function tear_down() {
// Force reset the database prefix after runner prepare method called.
global $wpdb, $table_prefix;
$wpdb->set_prefix( $table_prefix );
parent::tear_down();
}

public function test_is_plugin_check_returns_true() {
$_SERVER['argv'] = array(
'wp',
Expand Down
98 changes: 98 additions & 0 deletions tests/Checker/Runtime_Environment_Setup_Tests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php
/**
* Tests for the Checks class.
*
* @package plugin-check
*/

use WordPress\Plugin_Check\Checker\Runtime_Environment_Setup;

class Runtime_Environment_Setup_Tests extends WP_UnitTestCase {

public function test_setup() {
global $wp_filesystem, $wpdb;

$this->set_up_mock_filesystem();

$runtime_setup = new Runtime_Environment_Setup();
$runtime_setup->setup();

$this->assertTrue( 0 <= strpos( $wpdb->last_query, 'wppc_' ) );
$this->assertTrue( $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) );
$this->assertSame( file_get_contents( WP_PLUGIN_CHECK_PLUGIN_DIR_PATH . 'object-cache.copy.php' ), $wp_filesystem->get_contents( WP_CONTENT_DIR . '/object-cache.php' ) );
}

public function test_cleanup() {
global $wp_filesystem, $wpdb;

$this->set_up_mock_filesystem();

$runtime_setup = new Runtime_Environment_Setup();
$runtime_setup->setup();

// Simulate file exists by setting constant found in object-cache.php.
define( 'WP_PLUGIN_CHECK_OBJECT_CACHE_DROPIN_VERSION', 1 );

$runtime_setup->cleanup();

$this->assertTrue( 0 <= strpos( $wpdb->last_query, 'wppc_' ) );
$this->assertFalse( $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) );
Comment thread
jjgrainger marked this conversation as resolved.
}

public function test_setup_with_existing_object_cache() {
global $wp_filesystem, $wpdb;

$this->set_up_mock_filesystem();

// Simulate a different object-cache.php.
$dummy_file_content = '<?php /* Empty object-cache.php drop-in file. */';
$wp_filesystem->put_contents( WP_CONTENT_DIR . '/object-cache.php', $dummy_file_content );

$runtime_setup = new Runtime_Environment_Setup();
$runtime_setup->setup();

$this->assertTrue( 0 <= strpos( $wpdb->last_query, 'wppc_' ) );
$this->assertTrue( $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) );
$this->assertSame( $dummy_file_content, $wp_filesystem->get_contents( WP_CONTENT_DIR . '/object-cache.php' ) );
}

public function test_cleanup_with_existing_object_cache() {
global $wp_filesystem, $wpdb;

$this->set_up_mock_filesystem();

// Simulate a different object-cache.php.
$dummy_file_content = '<?php /* Empty object-cache.php drop-in file. */';
$wp_filesystem->put_contents( WP_CONTENT_DIR . '/object-cache.php', $dummy_file_content );

$runtime_setup = new Runtime_Environment_Setup();
$runtime_setup->setup();
$runtime_setup->cleanup();

$this->assertTrue( 0 <= strpos( $wpdb->last_query, 'wppc_' ) );
$this->assertTrue( $wp_filesystem->exists( WP_CONTENT_DIR . '/object-cache.php' ) );
$this->assertSame( $dummy_file_content, $wp_filesystem->get_contents( WP_CONTENT_DIR . '/object-cache.php' ) );
}

private function set_up_mock_filesystem() {
global $wp_filesystem;

add_filter(
'filesystem_method_file',
function() {
return __DIR__ . '/../testdata/Filesystem/WP_Filesystem_MockFilesystem.php';
}
);
add_filter(
'filesystem_method',
function() {
return 'MockFilesystem';
}
);

WP_Filesystem();

// Simulate that the original object-cache.copy.php file exists.
$wp_filesystem->put_contents( WP_PLUGIN_CHECK_PLUGIN_DIR_PATH . 'object-cache.copy.php', file_get_contents( WP_PLUGIN_CHECK_PLUGIN_DIR_PATH . 'object-cache.copy.php' ) );
}
}
Loading