PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / trunk
Image Optimizer – Compress Images and Convert to WebP or AVIF vtrunk
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
image-optimization / classes / image / image-backup.php

image-backup.php in Image Optimizer – Compress Images and Convert to WebP or AVIF trunk, at classes/image/image-backup.php

138 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ImageOptimization\Classes\Image;
4
5 use ImageOptimization\Classes\File_System\Exceptions\File_System_Operation_Error;
6 use ImageOptimization\Classes\File_System\File_System;
7 use ImageOptimization\Classes\File_Utils;
8 use ImageOptimization\Classes\Image\Exceptions\Image_Backup_Creation_Error;
9 use ImageOptimization\Classes\Logger;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 /**
16 * We're saving backup paths in meta even though the backup path could be dynamically generated.
17 * The next reasons affected this decision:
18 *
19 * 1. Possible path conflicts with other plugins and/or custom user logic. We can't guarantee that the image
20 * we find using the dynamically created path will be the same image we saved.
21 * 2. If a backup doesn't exist, but stored in our meta -- we can be almost sure it's not because of us.
22 * Probably, some other plugin removed it or even user manually did it, but it's not our fault. Makes this logic
23 * easier to debug.
24 * 3. We can change backup file name using `wp_unique_filename()` if needed and easily point a backup path to an
25 * image.
26 */
27 class Image_Backup {
28 /**
29 * Creates a backup of a file by copying it to a new file with the backup extension.
30 * Also, attaches a newly created backup to image's meta.
31 *
32 * @param int $image_id Attachment id.
33 * @param string $image_size Image size (e.g. 'full', 'thumbnail', etc.).
34 * @param string $image_path Path to an image we plan to back up.
35 *
36 * @return string Backup path if successfully created, false otherwise.
37 *
38 * @throws Image_Backup_Creation_Error
39 */
40 public static function create( int $image_id, string $image_size, string $image_path ): string {
41 $extension = File_Utils::get_extension( $image_path );
42 $backup_path = File_Utils::replace_extension( $image_path, "backup.$extension" );
43
44 try {
45 File_System::copy( $image_path, $backup_path, true );
46 } catch ( File_System_Operation_Error $e ) {
47 Logger::error(
48 "Error while creating a backup for image {$image_id} and size {$image_size}"
49 );
50
51 throw new Image_Backup_Creation_Error(
52 esc_html( "Error while creating a backup for image $image_id and size $image_size" )
53 );
54 }
55
56 $meta = new Image_Meta( $image_id );
57
58 $meta->set_image_backup_path( $image_size, $backup_path );
59 $meta->save();
60
61 return $backup_path;
62 }
63
64 /**
65 * Looks for registered backups and remove all files found.
66 * Also, wipes removed files from image meta.
67 *
68 * @param int[] $image_ids Array of attachment ids.
69 * @return void
70 */
71 public static function remove_many( array $image_ids ): void {
72 foreach ( $image_ids as $image_id ) {
73 self::remove( $image_id );
74 }
75 }
76
77 /**
78 * Removes one or all backups for a specific image.
79 * Also, wipes removed files from image meta.
80 *
81 * @param int $image_id Attachment id.
82 * @param string|null $image_size Image size (e.g. 'full', 'thumbnail', etc.). All backups will be removed if no size provided.
83 *
84 * @return bool Returns true if backups were removed successfully, false otherwise.
85 */
86 public static function remove( int $image_id, ?string $image_size = null ): bool {
87 $meta = new Image_Meta( $image_id );
88 $backups = $meta->get_image_backup_paths();
89
90 if ( empty( $backups ) ) {
91 return false;
92 }
93
94 if ( $image_size ) {
95 if ( ! key_exists( $image_size, $backups ) ) {
96 return false;
97 }
98
99 self::delete_backup_file( $image_id, $image_size, $backups[ $image_size ] );
100
101 $meta->remove_image_backup_path( $image_size );
102 $meta->save();
103
104 return true;
105 }
106
107 foreach ( $backups as $image_size => $backup_path ) {
108 self::delete_backup_file( $image_id, $image_size, $backup_path );
109
110 $meta->remove_image_backup_path( $image_size );
111 }
112
113 $meta->save();
114
115 return true;
116 }
117
118 private static function delete_backup_file( int $image_id, string $image_size, string $backup_path ): void {
119 $resolved_path = Image_Backup_Path_Validator::resolve( $backup_path );
120
121 if ( null === $resolved_path ) {
122 Logger::warn(
123 "Skipped removing invalid backup path for image {$image_id} and size {$image_size}"
124 );
125
126 return;
127 }
128
129 try {
130 File_System::delete( $resolved_path, false, 'f' );
131 } catch ( File_System_Operation_Error $fsoe ) {
132 Logger::error(
133 "Error while removing a backup for image {$image_id} and size {$image_size}"
134 );
135 }
136 }
137 }
138