diff --git a/src/class-tiny-apache-rewrite.php b/src/class-tiny-apache-rewrite.php index e6944d70..31b5aa12 100644 --- a/src/class-tiny-apache-rewrite.php +++ b/src/class-tiny-apache-rewrite.php @@ -24,7 +24,7 @@ * - inserting/removing rules from htaccess * * We are only updating rules when: - * - updating the option convert_format + * - adding or updating the option convert_format * - uninstalling the plug-in */ class Tiny_Apache_Rewrite extends Tiny_WP_Base { @@ -36,6 +36,19 @@ class Tiny_Apache_Rewrite extends Tiny_WP_Base { */ const MARKER = 'tiny-compress-images'; + /** + * Installs the htaccess rules when the option convert_format is saved + * for the first time, which adds it instead of updating it. + * hooked into `add_option_tinypng_convert_format` + * + * @param string $option + * @param mixed $value + * @return void + */ + public static function toggle_rules_for_new_option( $option, $value ) { + self::toggle_rules( null, $value, $option ); + } + /** * Installs or uninstalls the htaccess rules * hooked into `update_option_tinypng_convert_format` diff --git a/src/class-tiny-conversion.php b/src/class-tiny-conversion.php index 9934f1ad..b59b5765 100644 --- a/src/class-tiny-conversion.php +++ b/src/class-tiny-conversion.php @@ -37,18 +37,20 @@ public function __construct( $settings ) { } /** - * will check if conversion is enabled, - * if true: + * will add hooks to toggle rules when the conversion settings are saved, + * also while conversion is off, because saving is what turns it on. + * will check if conversion is enabled, if true: * - will enable the delivery method - * - will add hook to toggle rules * * hooked into `init` */ public function init() { - if ( ! $this->settings->get_conversion_enabled() ) { - return; - } - + add_action( + 'add_option_tinypng_convert_format', + 'Tiny_Apache_Rewrite::toggle_rules_for_new_option', + 20, + 2 + ); add_action( 'update_option_tinypng_convert_format', 'Tiny_Apache_Rewrite::toggle_rules', @@ -56,6 +58,10 @@ public function init() { 3 ); + if ( ! $this->settings->get_conversion_enabled() ) { + return; + } + $delivery_method = $this->settings->get_conversion_delivery_method(); $this->init_image_delivery( $delivery_method ); diff --git a/test/unit/Tiny_Apache_Rewrite_Test.php b/test/unit/Tiny_Apache_Rewrite_Test.php index 1174cab2..78009335 100644 --- a/test/unit/Tiny_Apache_Rewrite_Test.php +++ b/test/unit/Tiny_Apache_Rewrite_Test.php @@ -23,6 +23,62 @@ function test_plugin_init_will_add_hook() WordPressStubs::assertHook('update_option_tinypng_convert_format', 'Tiny_Apache_Rewrite::toggle_rules'); } + /** + * The request that turns conversion on still has it off during init, + * so the hook must be there to install the rules. + */ + function test_plugin_init_will_add_hook_when_conversion_is_off() + { + $GLOBALS['is_apache'] = false; + + $mock_settings = $this->createMock(Tiny_Settings::class); + $mock_settings->method('get_conversion_enabled')->willReturn(false); + + new Tiny_Conversion($mock_settings); + + $this->wp->init(); + + WordPressStubs::assertHook('update_option_tinypng_convert_format', 'Tiny_Apache_Rewrite::toggle_rules'); + } + + /** + * The first save of convert_format adds the option instead of updating it. + */ + function test_plugin_init_will_add_hook_for_new_option() + { + $GLOBALS['is_apache'] = false; + + $mock_settings = $this->createMock(Tiny_Settings::class); + $mock_settings->method('get_conversion_enabled')->willReturn(false); + + new Tiny_Conversion($mock_settings); + + $this->wp->init(); + + WordPressStubs::assertHook('add_option_tinypng_convert_format', 'Tiny_Apache_Rewrite::toggle_rules_for_new_option'); + } + + /** + * Saving convert_format for the first time with htaccess delivery + * inserts the rules in the upload directory. + */ + function test_toggle_rules_for_new_option_installs_upload_dir_htaccess() + { + $upload_dir = $this->vfs->url() . '/wp-content/uploads'; + $htaccess_file = $upload_dir . '/.htaccess'; + + if (!is_dir($upload_dir)) { + mkdir($upload_dir, 0755, true); + } + + Tiny_Apache_Rewrite::toggle_rules_for_new_option( + 'tinypng_convert_format', + array('convert' => 'on', 'delivery_method' => 'htaccess') + ); + + $this->assertStringContainsString('tiny-compress-images', file_get_contents($htaccess_file)); + } + /** * uninstall_rules removes htaccess rules from upload directory. * - creates a htaccess file in uploads directory