Skip to content

Commit 2dc0ccd

Browse files
use action to create filter
1 parent 45e082e commit 2dc0ccd

7 files changed

Lines changed: 127 additions & 131 deletions

File tree

docs/hooks/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The plugin provides several hooks to let you extend or modify its behavior.
66

77
- [updated_tiny_postmeta](updated_tiny_postmeta.md) — Triggered when tinify meta data has been updated
88
- [tiny_image_after_compression](tiny_image_after_compression.md) — Triggered after successful optimization.
9+
- [tiny_image_size_before_compression](tiny_image_size_before_compression.md) — Triggered before optimizing an image size.
10+
911

1012
## Filters
1113

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# tiny_image_size_before_compression
2+
3+
Action that is done before compressing an single image size.
4+
5+
**Location:** `src/class-tiny-image.php`
6+
**Since:** 3.7.0
7+
8+
## Arguments
9+
10+
1. `int $attachment_id` - The attachment ID.
11+
2. `int|string $size_name` - The image size name. 0 for the original.
12+
3. `string $filepath` - The file path to the image being compressed.
13+
14+
## Example
15+
16+
```php
17+
add_filter(
18+
'tiny_image_size_before_compression',
19+
function ( $attachment_id, $size_name, $filename ) {
20+
// notify system of compression
21+
}
22+
);
23+
```

src/class-tiny-image.php

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,25 @@ public function compress() {
221221
if ( ! $size->is_duplicate() ) {
222222
$size->add_tiny_meta_start();
223223
$this->update_tiny_post_meta();
224-
$backup_created = $this->create_backup( $size_name, $size->filename );
225-
$resize = $this->settings->get_resize_options( $size_name );
226-
$preserve = $this->settings->get_preserve_options( $size_name );
224+
225+
/**
226+
* Fires before an image size is sent for compression.
227+
*
228+
* @since 3.6.8
229+
*
230+
* @param int $attachment_id The attachment ID.
231+
* @param int|string $size_name The image size name. 0 for the original.
232+
* @param string $filepath The file path to the image being compressed.
233+
*/
234+
do_action(
235+
'tiny_image_size_before_compression',
236+
$this->id,
237+
$size_name,
238+
$size->filename
239+
);
240+
241+
$resize = $this->settings->get_resize_options( $size_name );
242+
$preserve = $this->settings->get_preserve_options( $size_name );
227243
Tiny_Logger::debug(
228244
'compress size',
229245
array(
@@ -239,7 +255,6 @@ public function compress() {
239255
'has_been_compressed' => $size->has_been_compressed(),
240256
'filesize' => $size->filesize(),
241257
'mimetype' => $size->mimetype(),
242-
'backup' => $backup_created,
243258
)
244259
);
245260
try {
@@ -607,39 +622,4 @@ public function mark_as_compressed() {
607622

608623
$this->update_tiny_post_meta();
609624
}
610-
611-
/**
612-
* creates a backup of the image as <originalfile>.bak.<extension>
613-
*
614-
* @param string $size_name name of the size
615-
* @param string $filepath path to file that needs backup
616-
* @return bool true when backup is created
617-
*/
618-
private function create_backup( $size_name, $filepath ) {
619-
if ( ! $this->needs_backup( $size_name ) ) {
620-
return false;
621-
}
622-
623-
$fileinfo = pathinfo( $filepath );
624-
$backup_file = sprintf(
625-
'%s%s.bak.%s',
626-
trailingslashit( $fileinfo['dirname'] ),
627-
$fileinfo['filename'],
628-
$fileinfo['extension']
629-
);
630-
631-
return copy( $filepath, $backup_file );
632-
}
633-
634-
/**
635-
* @param string $size_name name of the size
636-
* @return bool true when backup needs to be created
637-
*/
638-
private function needs_backup( $size_name ) {
639-
if ( ! self::is_original( $size_name ) ) {
640-
return false;
641-
}
642-
643-
return $this->settings->get_backup_enabled();
644-
}
645625
}

src/class-tiny-plugin.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ public function init() {
6767

6868
add_action( 'delete_attachment', $this->get_method( 'clean_attachment' ), 10, 2 );
6969

70+
add_action(
71+
'tiny_image_size_before_compression',
72+
$this->get_method( 'backup_image_size' ),
73+
10,
74+
3
75+
);
76+
7077
load_plugin_textdomain(
7178
self::NAME,
7279
false,
@@ -861,6 +868,43 @@ public function clean_attachment( $post_id ) {
861868
$tiny_image->delete_converted_image();
862869
}
863870

871+
/**
872+
* Creates a backup of an image size before compression.
873+
*
874+
* Hooked to the `tiny_image_size_before_compression` action. Only creates
875+
* a backup for the original image size when the backup setting is enabled.
876+
* The backup is stored under {upload_dir}/tinify_backup/, preserving the
877+
* original path structure relative to the uploads base directory.
878+
*
879+
* @since 3.6.8
880+
*
881+
* @param int $image_id The attachment ID.
882+
* @param int|string $size_name The image size name. 0 for the original.
883+
* @param string $filepath The file path to the image to be backed up.
884+
* @return bool return true on backup created
885+
*/
886+
public function backup_image_size( $image_id, $size_name, $filepath ) {
887+
if ( ! Tiny_Image::is_original( $size_name ) ) {
888+
return false;
889+
}
890+
891+
if ( ! $this->settings->get_backup_enabled() ) {
892+
return false;
893+
}
894+
895+
$upload_dir = wp_upload_dir();
896+
$upload_base = trailingslashit( $upload_dir['basedir'] );
897+
$relative_path = ltrim( str_replace( $upload_base, '', $filepath ), '/' );
898+
$backup_file = $upload_base . 'tinify_backup/' . $relative_path;
899+
$backup_dir = dirname( $backup_file );
900+
901+
if ( ! wp_mkdir_p( $backup_dir ) ) {
902+
return false;
903+
}
904+
905+
return copy( $filepath, $backup_file );
906+
}
907+
864908
public static function request_review() {
865909
$review_url =
866910
'https://wordpress.org/support/plugin/tiny-compress-images/reviews/#new-post';

test/helpers/wordpress.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ public function getTestMetadata($path = '14/01', $name = 'test')
353353
*/
354354
public static function assertHook($hookname, $expected_args = null)
355355
{
356-
$hooks = array('add_action', 'add_filter');
356+
$hooks = array('add_action', 'add_filter', 'do_action', 'apply_filters');
357357
$found = false;
358358

359359
foreach ($hooks as $method) {
@@ -416,7 +416,7 @@ public function current_time()
416416
*/
417417
public function wp_mkdir_p($dir)
418418
{
419-
mkdir($dir, 0755, true);
419+
return mkdir($dir, 0755, true) || is_dir($dir);
420420
}
421421

422422
/**

test/unit/TinyImageTest.php

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -307,93 +307,4 @@ public function test_conversion_same_mimetype()
307307
$this->assertEquals(array('image/webp'), $compress_calls[1]['convert_to']);
308308
}
309309

310-
public function test_creates_backup_of_original_image() {
311-
$this->wp->addOption('tinypng_backup', array(
312-
'enabled' => 'on',
313-
));
314-
$this->wp->addOption('tinypng_sizes', array(
315-
Tiny_Image::ORIGINAL => 'on',
316-
));
317-
$this->wp->stub('get_post_mime_type', function () {
318-
return 'image/png';
319-
});
320-
321-
$input_dir = '26/03';
322-
$input_name = 'testforbackup';
323-
$this->wp->createImages(array(), 1000, $input_dir, $input_name);
324-
325-
$settings = new Tiny_Settings();
326-
$mock_compressor = $this->createMock(Tiny_Compress::class);
327-
$settings->set_compressor($mock_compressor);
328-
329-
$metadata = $this->wp->getTestMetadata($input_dir, $input_name);
330-
$tinyimg = new Tiny_Image($settings, 999, $metadata);
331-
$tinyimg->compress();
332-
333-
$this->assertTrue(
334-
file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) ,
335-
'backup of file should be created');
336-
}
337-
338-
public function test_will_not_backup_other_sizes() {
339-
$this->wp->addOption('tinypng_backup', array(
340-
'enabled' => 'on',
341-
));
342-
$this->wp->addOption('tinypng_sizes', array(
343-
'thumbnail' => 'on',
344-
));
345-
$this->wp->stub('get_post_mime_type', function () {
346-
return 'image/png';
347-
});
348-
349-
$input_dir = '26/03';
350-
$input_name = 'testforbackup';
351-
$this->wp->createImages(array(
352-
'thumbnail' => 1000,
353-
), 1000, $input_dir, $input_name);
354-
355-
$settings = new Tiny_Settings();
356-
$mock_compressor = $this->createMock(Tiny_Compress::class);
357-
$settings->set_compressor($mock_compressor);
358-
359-
$metadata = $this->wp->getTestMetadata($input_dir, $input_name);
360-
$tinyimg = new Tiny_Image($settings, 999, $metadata);
361-
$tinyimg->compress();
362-
363-
$this->assertFalse(
364-
file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) ,
365-
'backup of original should not exist');
366-
367-
$this->assertFalse(
368-
file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '-thumbnail.bak.png' ) ,
369-
'backup of thumbnail should not exist');
370-
}
371-
372-
public function test_will_not_backup_when_disabled() {
373-
$this->wp->addOption('tinypng_backup', array(
374-
'enabled' => false,
375-
));
376-
$this->wp->addOption('tinypng_sizes', array(
377-
Tiny_Image::ORIGINAL => 'on',
378-
));
379-
$this->wp->stub('get_post_mime_type', function () {
380-
return 'image/png';
381-
});
382-
383-
$input_dir = '26/03';
384-
$input_name = 'testforbackup';
385-
$this->wp->createImages(array(), 1000, $input_dir, $input_name);
386-
387-
$settings = new Tiny_Settings();
388-
$mock_compressor = $this->createMock(Tiny_Compress::class);
389-
$settings->set_compressor($mock_compressor);
390-
391-
$metadata = $this->wp->getTestMetadata($input_dir, $input_name);
392-
$tinyimg = new Tiny_Image($settings, 999, $metadata);
393-
$tinyimg->compress();
394-
395-
$this->assertFalse(
396-
file_exists( $this->vfs->url() . '/wp-content/uploads/' . $input_dir . '/' . $input_name . '.bak.png' ) ,
397-
'backup of original should not exist');
398-
}
399310
}

test/unit/TinyPluginTest.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
require_once dirname(__FILE__) . '/TinyTestCase.php';
44

55
use org\bovigo\vfs\vfsStream;
6-
use org\bovigo\vfs\content\LargeFileContent;
6+
7+
use function PHPUnit\Framework\assertFalse;
8+
use function PHPUnit\Framework\assertTrue;
79

810
class Tiny_Plugin_Test extends Tiny_TestCase
911
{
@@ -495,4 +497,38 @@ public function test_conversion_enabled_and_not_filtered()
495497

496498
WordPressStubs::assertHook('template_redirect', array($tiny_picture, 'on_template_redirect'));
497499
}
500+
501+
public function test_init_adds_backup_image_size_action() {
502+
$tiny_plugin = new Tiny_Plugin();
503+
$tiny_plugin->init();
504+
505+
// assert that backup is hooked into `tiny_image_size_before_compression`
506+
WordPressStubs::assertHook('tiny_image_size_before_compression', array($tiny_plugin, 'backup_image_size'));
507+
}
508+
509+
public function test_will_copy_original_file_on_backup() {
510+
$this->wp->createImage( 37857, '2026/04', 'testfile.png' );
511+
$og_file_path = $this->vfs->url() . '/wp-content/uploads/2026/04/testfile.png';
512+
$expected_backup = $this->vfs->url() . '/wp-content/uploads/tinify_backup/2026/04/testfile.png';
513+
514+
$tiny_plugin = new Tiny_Plugin();
515+
516+
$ref = new \ReflectionClass($tiny_plugin);
517+
$settings_prop = $ref->getProperty('settings');
518+
$settings_prop->setAccessible(true);
519+
$mock_settings = $this->createMock(Tiny_Settings::class);
520+
$mock_settings->method('get_backup_enabled')->willReturn(true);
521+
$settings_prop->setValue($tiny_plugin, $mock_settings);
522+
523+
$tiny_plugin->backup_image_size(1, 0, $og_file_path);
524+
525+
assertTrue(file_exists($expected_backup), 'expected backup to be created');
526+
}
527+
528+
public function test_when_not_original_will_not_backup() {
529+
$tiny_plugin = new Tiny_Plugin();
530+
$created = $tiny_plugin->backup_image_size(1, 'thumbnail', 'filepath');
531+
532+
assertFalse($created, 'expected backup not te be created');
533+
}
498534
}

0 commit comments

Comments
 (0)