Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 4472 - Display notice when DelayJS is activated with Autoptimize Aggregate JS already in effect #4501

Merged
Show file tree
Hide file tree
Changes from 18 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
21 changes: 9 additions & 12 deletions inc/Engine/Optimization/DelayJS/Admin/Subscriber.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
declare(strict_types=1);
declare( strict_types=1 );

namespace WP_Rocket\Engine\Optimization\DelayJS\Admin;

Expand Down Expand Up @@ -40,26 +40,25 @@ public static function get_subscribed_events() {
/**
* Add the delay JS options to the WP Rocket options array
*
* @since 3.7
*
* @param array $options WP Rocket options array.
*
* @return array
* @since 3.7
*/
public function add_options( $options ) : array {
public function add_options( $options ): array {
return $this->settings->add_options( $options );
}

/**
* Sets the delay_js_exclusions default value for users with delay JS enabled on upgrade
*
* @since 3.9 Sets the delay_js_exclusions default value if delay_js is 1
* @since 3.7
*
* @param string $new_version New plugin version.
* @param string $old_version Previous plugin version.
*
* @return void
* @since 3.7
*
* @since 3.9 Sets the delay_js_exclusions default value if delay_js is 1
*/
public function set_option_on_update( $new_version, $old_version ) {
$this->settings->set_option_on_update( $old_version );
Expand All @@ -68,26 +67,24 @@ public function set_option_on_update( $new_version, $old_version ) {
/**
* Sanitizes Delay JS options values when the settings form is submitted
*
* @since 3.9
*
* @param array $input Array of values submitted from the form.
* @param AdminSettings $settings Settings class instance.
*
* @return array
* @since 3.9
*/
public function sanitize_options( $input, AdminSettings $settings ) : array {
public function sanitize_options( $input, AdminSettings $settings ): array {
return $this->settings->sanitize_options( $input, $settings );
}

/**
* Disable combine JS option when delay JS is enabled
*
* @since 3.9
*
* @param array $value The new, unserialized option value.
* @param array $old_value The old option value.
*
* @return array
* @since 3.9
*/
public function maybe_disable_combine_js( $value, $old_value ): array {
return $this->settings->maybe_disable_combine_js( $value, $old_value );
Expand Down
1 change: 1 addition & 0 deletions inc/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ private function init_common_subscribers() {
'ewww_webp_subscriber',
'optimus_webp_subscriber',
'adthrive',
'autoptimize',
'wp-meteor',
'revolution_slider_subscriber',
'wordfence_subscriber',
Expand Down
106 changes: 106 additions & 0 deletions inc/ThirdParty/Plugins/Optimization/Autoptimize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare( strict_types=1 );

namespace WP_Rocket\ThirdParty\Plugins\Optimization;

use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Event_Management\Subscriber_Interface;

class Autoptimize implements Subscriber_Interface {
/**
* WP Rocket Options instance
*
* @var Options_Data
*/
private $options;

/**
* Array containing the errors
*
* @var array
*/
private $errors = [];

/**
* Constructor
*
* @param Options_Data $options WP Rocket Options instance.
*/
public function __construct( Options_Data $options ) {
$this->options = $options;
}

/**
* Return an array of events that this subscriber listens to.
*
* @return array
* @since 3.10.4
*/
public static function get_subscribed_events() {
return [
'admin_notices' => [ 'warn_when_js_aggregation_and_delay_js_active' ],
];
}

/**
* Add an admin warning notice when Delay JS and JS Aggregation are both activated.
*
* @since 3.10.4
*/
public function warn_when_js_aggregation_and_delay_js_active() {
if ( ! rocket_get_constant( 'AUTOPTIMIZE_PLUGIN_VERSION', false ) ) {
iCaspar marked this conversation as resolved.
Show resolved Hide resolved
return;
}
iCaspar marked this conversation as resolved.
Show resolved Hide resolved

if ( ! current_user_can( 'rocket_manage_options' ) ) {
return;
}

$autoptimize_aggregate_js_setting = get_option( 'autoptimize_js_aggregate' );
$boxes = get_user_meta( get_current_user_id(), 'rocket_boxes', true );

if ( 'on' !== $autoptimize_aggregate_js_setting || false === (bool) $this->options->get( 'delay_js' ) ) {
if ( ! is_array( $boxes ) ) {
return;
}

$this->remove_warning_dismissal( $boxes, __FUNCTION__ );

return;
}

if ( in_array( __FUNCTION__, (array) $boxes, true ) ) {
return;
}

$message = '<strong>' . __(
'We have detected that Autoptimize\'s JavaScript Aggregation feature is enabled. The Delay JavaScript Execution will not be applied to the file it creates. We suggest disabling it to take full advantage of Delay JavaScript Execution.',
'rocket'
) . '</strong>';

rocket_notice_html(
[
'status' => 'warning',
'message' => $message,
'dismissable' => '',
'dismiss_button' => __FUNCTION__,
]
);
}

/**
* Remove a warning box dismissal.
*
* @param array $boxes The rocket_boxes user meta.
* @param string $name Slug for the box to be removed.
*/
private function remove_warning_dismissal( $boxes, $name ) {
if ( ! in_array( $name, $boxes, true ) ) {
return;
}

unset( $boxes[ array_search( $name, $boxes, true ) ] );
update_user_meta( get_current_user_id(), 'rocket_boxes', $boxes );
}
}
5 changes: 5 additions & 0 deletions inc/ThirdParty/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class ServiceProvider extends AbstractServiceProvider {
'divi',
'mod_pagespeed',
'adthrive',
'autoptimize',
'wp-meteor',
'revolution_slider_subscriber',
'wordfence_subscriber',
Expand Down Expand Up @@ -131,6 +132,10 @@ public function register() {
$this->getContainer()
->share( 'adthrive', 'WP_Rocket\ThirdParty\Plugins\Ads\Adthrive' )
->addTag( 'common_subscriber' );
$this->getContainer()
->share( 'autoptimize', 'WP_Rocket\ThirdParty\Plugins\Optimization\Autoptimize' )
->addArgument( $options )
->addTag( 'common_subscriber' );
$this->getContainer()
->share( 'wp-meteor', 'WP_Rocket\ThirdParty\Plugins\Optimization\WPMeteor' )
->addTag( 'common_subscriber' );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare( strict_types=1 );

$expected_html = <<<HTML
<div class="notice notice-warning is-dismissible">
<p>
<strong>
We have detected that Autoptimize's JavaScript Aggregation feature is enabled. The Delay JavaScript Execution will not be applied to the file it creates. We suggest disabling it to take full advantage of Delay JavaScript Execution.</strong>
</p>
<p>
<a class="rocket-dismiss" href="http://example.org/wp-admin/admin-post.php?action=rocket_ignore&amp;box=warn_when_js_aggregation_and_delay_js_active&amp;_wpnonce=123456">
Dismiss this notice.</a></p></div>
HTML;

return [
'shouldAddNoticeWhenAutoptimizeAggregateJsOnAndDelayJsActivated' => [
'config' => [
'delayJSActive' => true,
'autoptimizeAggregateJSActive' => 'on',
'dismissed' => false,
],
'expected' => $expected_html
],

'shouldSkipWhenAutoptimizeAggregateJsOffAndDelayJsNotActivated' => [
'config' => [
'delayJSActive' => false,
'autoptimizeAggregateJSActive' => 'off',
'dismissed' => false,
],
'expected' => '',
],

'shouldSkipWhenAutoptimizeAggregateJsOffAndDelayJsActivated' => [
'config' => [
'delayJSActive' => true,
'autoptimizeAggregateJSActive' => 'off',
'dismissed' => false,
],
'expected' => '',
],

'shouldSkipWhenAutoptimizeAggregateJsOnAndDelayJsNotActivated' => [
'config' => [
'delayJSActive' => false,
'autoptimizeAggregateJSActive' => 'on',
'dismissed' => false,
],
'expected' => '',
],

'shouldSkipWhenUserHasDismissedNotice' => [
'config' => [
'delayJSActive' => true,
'autoptimizeAggregateJSActive' => 'on',
'dismissed' => true,
],
'expected' => '',
],

'shouldClearDismissalWhenUserDeactivatesDelayJS' => [
'config' => [
'delayJSActive' => false,
'autoptimizeAggregateJSActive' => 'on',
'dismissed' => true,
],
'expected' => '',
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

declare( strict_types=1 );

use Brain\Monkey\Functions;
use WP_Rocket\Tests\Integration\CapTrait;
use WP_Rocket\Tests\Integration\TestCase;

/**
* @covers WP_Rocket\ThirdParty\Plugins\Optimization\Autoptimize::warn_when_js_aggregation_and_delay_js_active
*
* @group Autoptimize
* @group AdminOnly
* @group ThirdParty
*/
class Test_WarnWhenJsAggregationAndDelayJsActive extends TestCase {
use CapTrait;

public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();

CapTrait::setAdminCap();
}

public function setUp(): void {
parent::setUp();

$this->unregisterAllCallbacksExcept(
'admin_notices',
'warn_when_js_aggregation_and_delay_js_active'
);

Functions\expect( 'wp_create_nonce' )
->with( 'warn_when_js_aggregation_and_delay_js_active' )
->andReturn( '123456' );
}

public function tearDown() {
$this->restoreWpFilter( 'admin_notices' );
parent::tearDown();
}

/**
* @dataProvider configTestData
*/
public function testShouldAddExpectedNotice( $config, $expected ) {
$this->constants['AUTOPTIMIZE_PLUGIN_VERSION'] = '1.2.3';
$this->stubRocketGetConstant();

$current_user = static::factory()->user->create( [ 'role' => 'administrator' ] );
wp_set_current_user( $current_user );

update_option( 'autoptimize_js_aggregate', $config['autoptimizeAggregateJSActive'] );
add_filter( 'pre_get_rocket_option_delay_js', function () use ( $config ) {
return $config[ 'delayJSActive' ];
} );

if ( $config['dismissed'] ) {
update_user_meta(
$current_user,
'rocket_boxes',
[ 'warn_when_js_aggregation_and_delay_js_active' ]
);
}

ob_start();
do_action( 'admin_notices' );
$notices = ob_get_clean();
$notices = empty( $notices ) ? $notices : $this->format_the_html( $notices );

$this->assertSame( $this->format_the_html( $expected ), $notices );

$boxes = get_user_meta( $current_user, 'rocket_boxes', true );

if ( $config[ 'dismissed' ]
&&
$config[ 'delayJSActive']
&&
$config[ 'autoptimizeAggregateJSActive' ]
) {
$this->assertContains( 'warn_when_js_aggregation_and_delay_js_active', $boxes );
}

if (
$config[ 'dismissed' ]
&&
( ! $config[ 'delayJSActive' ] || 'off' === $config[ 'autoptimizeAggregateJSActive' ] )
) {
$this->assertNotContains('warn_when_js_aggregation_and_delay_js_active', $boxes );
}
}
}