Skip to content

Commit

Permalink
fix: cleanup constants and refactor autoload handling
Browse files Browse the repository at this point in the history
  • Loading branch information
justlevine committed Sep 11, 2024
1 parent a06f97a commit b2516bf
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-buttons-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wpengine/wp-graphql-content-blocks": minor
---

fix: cleanup constants and refactor autoload handling to improve Composer compatibility.
125 changes: 125 additions & 0 deletions includes/Autoloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
/**
* Includes the Composer Autoloader used for packages and classes in the includes/ directory.
*
* @package WPGraphQL\ContentBlocks
* @since @todo
*/

declare( strict_types = 1 );

namespace WPGraphQL\ContentBlocks;

/**
* Class - Autoloader
*
* @internal
*/
class Autoloader {
/**
* Whether the autoloader has been loaded.
*
* @var bool
*/
protected static bool $is_loaded = false;

/**
* Attempts to autoload the Composer dependencies.
*/
public static function autoload(): bool {
// If we're not *supposed* to autoload anything, then return true.
if ( defined( 'WPGRAPHQL_CONTENT_BLOCKS_AUTOLOAD' ) && false === WPGRAPHQL_CONTENT_BLOCKS_AUTOLOAD ) {
return true;
}

// If the autoloader has already been loaded, then return true.
if ( self::$is_loaded ) {
return self::$is_loaded;
}

// If the main class has already been loaded, then they must be using a different autoloader.
if ( class_exists( 'WPGraphQLContentBlocks' ) ) {
return true;
}

$autoloader = dirname( __DIR__ ) . '/vendor/autoload.php';
self::$is_loaded = self::require_autoloader( $autoloader );

return self::$is_loaded;
}

/**
* Attempts to load the autoloader file, if it exists.
*
* @param string $autoloader_file The path to the autoloader file.
*/
private static function require_autoloader( string $autoloader_file ): bool {
if ( ! is_readable( $autoloader_file ) ) {
self::missing_autoloader_notice();
return false;
}

return (bool) require_once $autoloader_file; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable -- Autoloader is a Composer file.
}

/**
* Displays a notice if the autoloader is missing.
*/
private static function missing_autoloader_notice(): void {
$error_message = __( 'WPGraphQL Content Blocks appears to have been installed without its dependencies. If you meant to download the source code, you can run `composer install` to install dependencies. If you are looking for the production version of the plugin, you can download it from the <a target="_blank" href="https://github.com/wpengine/wp-graphql-content-blocks/releases">GitHub Releases tab.</a>', 'wp-graphql-content-blocks' );

if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- This is a development notice.
sprintf(
wp_kses(
$error_message,
[
'a' => [
'href' => [],
'target' => [],
],
]
)
)
);
}

$hooks = [
'admin_notices',
'network_admin_notices',
];

foreach ( $hooks as $hook ) {
add_action(
$hook,
static function () use ( $error_message ) {

// Only show the notice to admins.
if ( ! current_user_can( 'manage_options' ) ) {
return;
}

?>
<div class="error notice">
<p>
<?php
printf(
wp_kses(
$error_message,
[
'a' => [
'href' => [],
'target' => [],
],
]
)
)
?>
</p>
</div>
<?php
}
);
}
}
}
68 changes: 68 additions & 0 deletions tests/unit/AutoloaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace WPGraphQL\ContentBlocks\Unit;

use WPGraphQL\ContentBlocks\Autoloader;

class MockAutoloader extends Autoloader {
public static function reset() {
self::$is_loaded = false;
}
}

/**
* Tests the main class.
*/
final class AutoloaderTest extends PluginTestCase {
protected $autoloader;

public function setUp(): void {
$this->autoloader = new MockAutoloader();
MockAutoloader::reset();

parent::setUp();
}

public function tearDown(): void {
unset( $this->autoloader );

parent::tearDown();
}

public function testAutoload() {
$this->assertTrue( $this->autoloader->autoload() );
}

public function testRequireAutoloader() {
$reflection = new \ReflectionClass( $this->autoloader );
$is_loaded_property = $reflection->getProperty( 'is_loaded' );
$is_loaded_property->setAccessible( true );
$is_loaded_property->setValue( $this->autoloader, false );

$method = $reflection->getMethod( 'require_autoloader' );
$method->setAccessible( true );


$this->assertTrue( $method->invokeArgs( $this->autoloader, [ WPGRAPHQL_CONTENT_BLOCKS_PLUGIN_DIR . '/vendor/autoload.php' ] ) );

$is_loaded_property->setValue( $this->autoloader, false );
$this->assertFalse( $method->invokeArgs( $this->autoloader, [ '/path/to/invalid/autoload.php' ] ) );

// Capture the admin notice output

$admin_id = $this->factory->user->create( [ 'role' => 'administrator' ] );

wp_set_current_user( $admin_id );

set_current_screen( 'dashboard' );
ob_start();
do_action( 'admin_notices' );

$output = ob_get_clean();
$this->assertStringContainsString( 'WPGraphQL Content Blocks appears to have been installed without its dependencies.', $output );

// Cleanup
wp_delete_user( $admin_id );
remove_all_actions( 'admin_notices' );
}
}
22 changes: 22 additions & 0 deletions tests/unit/UpdateCallbacksTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Class TestUpdateCallbacks
*/
class UpdateCallbacksTest extends WP_UnitTestCase {
public function test_pre_set_site_transient_update_plugins_has_filter_added(): void {
self::assertSame( 10, has_action( 'pre_set_site_transient_update_plugins', 'WPGraphQL\ContentBlocks\PluginUpdater\check_for_plugin_updates' ) );
}

public function test_plugins_api_has_filter_added(): void {
self::assertSame( 10, has_action( 'plugins_api', 'WPGraphQL\ContentBlocks\PluginUpdater\custom_plugin_api_request' ) );
}

public function test_admin_notices_has_actions_added(): void {
self::assertSame( 10, has_action( 'admin_notices', 'WPGraphQL\ContentBlocks\PluginUpdater\delegate_plugin_row_notice' ) );
self::assertSame( 10, has_action( 'admin_notices', 'WPGraphQL\ContentBlocks\PluginUpdater\display_update_page_notice' ) );
}

public function test_semantic_versioning_notice_text_has_filter_added(): void {
self::assertSame( 10, has_filter( 'semantic_versioning_notice_text', 'WPGraphQL\ContentBlocks\PluginUpdater\filter_semver_notice_text', 10, 2 ) );
}
}

0 comments on commit b2516bf

Please sign in to comment.