Skip to content

Commit

Permalink
Fix 4472 - Display notice when DelayJS is activated with Autoptimize …
Browse files Browse the repository at this point in the history
…Aggregate JS already in effect (#4501)

* Add tests and method for AO agg-js and wpr delayjs

* Fix param order in docblock

* Use add_settings_error instead of transient

* Fix docblock order

* Remove dead transient_errrors code

* Remove extra spacing

* Use matching priority in test

* Remove using void thing.

* Move warning method to new Compat Subscriber

* Reconfigure for new story conditions

* Add Autoptimize class to container

* Remove dead code from DelayJs Subscriber

* Move test to ThirdParty

* Check failing test

This will display the notice as expected, but the integration test will not run in isolation. Other functions from preload still run on admin_notice.

* Fix phpcs

* Revise tests and make pass

* Fix open/close strong tags

* Fix strong tags in test

* Remove extra dismiss icon
  • Loading branch information
iCaspar authored Nov 23, 2021
1 parent 0e4d2e9 commit d45314e
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 12 deletions.
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 ) ) {
return;
}

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,
'dismissible' => '',
'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 ">
<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 );
}
}
}

0 comments on commit d45314e

Please sign in to comment.