PluginProbe ʕ •ᴥ•ʔ
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF / trunk
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF vtrunk
2.0.5 trunk 1.3.7 1.4.0 1.4.1 1.4.2 1.4.6 1.5.0 1.5.3 1.5.6 1.5.8 1.6.5 1.6.6 1.6.9 1.7.0 1.7.4 1.8.1 1.8.2 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4
robin-image-optimizer / libs / addons / includes / classes / class.backup.php
robin-image-optimizer / libs / addons / includes / classes Last commit date
format 3 months ago helpers 5 months ago models 5 months ago webp 3 months ago class.backup.php 5 months ago class.custom-folders.php 5 months ago class.folder-image.php 5 months ago class.folder.php 5 months ago class.folders-list-table.php 5 months ago class.gallery-nextgen.php 5 months ago class.image-nextgen.php 5 months ago class.image-statistic-folders.php 5 months ago class.image-statistic-nextgen.php 5 months ago class.wpcli-optimize.php 5 months ago index.php 5 months ago
class.backup.php
361 lines
1 <?php
2
3 // Exit if accessed directly
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * Класс для работы с резервным копированием изображений
10 *
11 * @version 1.0
12 */
13 class WRIOP_Backup extends WIO_Backup {
14
15 const CF_BACKUP_DIR_NAME = 'custom-folders';
16 const NEXTGEN_BACKUP_DIR_NAME = 'nextgen-gallery';
17
18 /**
19 * The single instance of the class.
20 *
21 * @since 1.3.0
22 * @access protected
23 * @var object
24 */
25 protected static $_instance;
26
27 /**
28 * Получает путь к папке с резервными копиями
29 *
30 * @param array $gallery_meta метаданные аттачмента
31 *
32 * @return string
33 */
34 public function getNextgenBackupDir( $gallery_meta ) {
35 $backup_dir = $this->getBackupDir();
36 $backup_dir .= self::NEXTGEN_BACKUP_DIR_NAME . '/' . $gallery_meta->gid;
37
38 if ( ! is_dir( $backup_dir ) ) {
39 $backup_dir = $this->mkdir( $backup_dir );
40
41 if ( is_wp_error( $backup_dir ) ) {
42 return $backup_dir;
43 }
44 }
45
46 return trailingslashit( $backup_dir );
47 }
48
49 /**
50 * Делаем резервную копию NextGEN
51 *
52 * @param WRIO_Image_Nextgen $nextgen_image аттачмент
53 *
54 * @return bool|WP_Error
55 */
56 public function backupNextgen( $nextgen_image ) {
57 $backup_origin_images = WRIO_Plugin::app()->getPopulateOption( 'backup_origin_images', false );
58
59 if ( ! $backup_origin_images ) {
60 return false; // если бекап не требуется
61 }
62
63 $original_file = $nextgen_image->get( 'path' );
64 $original_thumbnail_file = $nextgen_image->get( 'thumbnail_path' );
65 $backup_dir = $this->getNextgenBackupDir( $nextgen_image->get( 'gallery_meta' ) );
66
67 if ( is_wp_error( $backup_dir ) ) {
68 return $backup_dir;
69 }
70
71 $backup_file = $backup_dir . $nextgen_image->get( 'file' );
72
73 if ( is_file( $original_file ) ) {
74 if ( ! @copy( $original_file, $backup_file ) ) {
75 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to swap original file %s with %s as copy() failed', $backup_file, $original_file ) );
76
77 return false;
78 }
79 }
80
81 $backup_thumbnail_file = $backup_dir . $nextgen_image->get( 'thumbnail_file' );
82
83 if ( is_file( $original_thumbnail_file ) ) {
84 if ( @copy( $original_thumbnail_file, $backup_thumbnail_file ) ) {
85 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to swap thumbnail file %s with %s as copy() failed', $backup_thumbnail_file, $original_thumbnail_file ) );
86
87 return false;
88 }
89 }
90
91 return true;
92 }
93
94 /**
95 * Restore NextGen images piece by piece.
96 *
97 * @param int $limit Limit on number of NextGen image to restore. Default: 50, maximum 1000.
98 *
99 * @return array {
100 * Result of process: how many images restored and how many remain.
101 * @type int $processed Count of processed images.
102 * @type int $remane Count of remained images to be processed.
103 * }
104 */
105 public function restoreAllNextGen( $limit = 50 ) {
106
107 if ( ! is_numeric( $limit ) || is_numeric( $limit ) && $limit > 1000 ) {
108 $limit = 50;
109 }
110
111 $queue_table = RIO_Process_Queue::table_name();
112 $nextgen_sql = "SELECT * FROM {$queue_table} WHERE `item_type` = %s AND `result_status` = %s LIMIT %d";
113
114 global $wpdb;
115
116 $nextgen_images = $wpdb->get_results( $wpdb->prepare( $nextgen_sql, 'nextgen', RIO_Process_Queue::STATUS_SUCCESS, $limit ) );
117
118 $result = [
119 'processed' => 0,
120 'remane' => 0,
121 ];
122
123 if ( empty( $nextgen_images ) ) {
124 return $result;
125 }
126
127 foreach ( $nextgen_images as $nextgen_image ) {
128 $nextgen_model = new WRIO_Image_Nextgen( $nextgen_image->object_id );
129
130 $restored = $nextgen_model->restore();
131
132 if ( ! is_wp_error( $restored ) ) {
133 $result['processed'] = $result['processed']++;
134 } else {
135 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to restore nextgen image ID: %s as %s::%s failed with message: %s', $nextgen_image->object_id, get_class( 'WRIO_Image_Nextgen' ), 'restore()', $restored->get_error_message() ) );
136 }
137 }
138
139 $nextgen_sql_remane = "SELECT COUNT(*) AS remane FROM {$queue_table} WHERE `item_type` = %s AND `result_status` = %s";
140
141 $nextgen_image_remane = $wpdb->get_var( $wpdb->prepare( $nextgen_sql_remane, 'nextgen', RIO_Process_Queue::STATUS_SUCCESS ) );
142
143 if ( $nextgen_image_remane === null ) {
144 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to get remained number of nextgen image by SQL: %s', $nextgen_sql_remane ) );
145 }
146
147 $result['remane'] = $nextgen_image_remane !== null ? (int) $nextgen_image_remane : 0;
148
149 if ( $result['remane'] === 0 ) {
150 // Should empty original/optimized size once all backups are empty
151 WRIO_Plugin::app()->updateOption( 'nextgen_original_size', 0 );
152 WRIO_Plugin::app()->updateOption( 'nextgen_optimized_size', 0 );
153 }
154
155 return $result;
156 }
157
158 /**
159 * Restore Custom Folders piece by piece.
160 *
161 * @param int $limit Limit on number of Custom Folders to restore. Default: 50, maximum 1000.
162 *
163 * @return array {
164 * Result of process: how many folders restored and how many remain.
165 * @type int $processed Count of processed folders.
166 * @type int $remane Count of remained folders to be processed.
167 * }
168 */
169 public function restoreAllCustomFolders( $limit = 50 ) {
170 if ( ! is_numeric( $limit ) || is_numeric( $limit ) && $limit > 1000 ) {
171 $limit = 50;
172 }
173
174 $queue_table = RIO_Process_Queue::table_name();
175 $cf_sql = "SELECT * FROM {$queue_table} WHERE `item_type` = %s AND `result_status` = %s LIMIT %d";
176
177 global $wpdb;
178
179 $cf_images = $wpdb->get_results( $wpdb->prepare( $cf_sql, 'cf_image', RIO_Process_Queue::STATUS_SUCCESS, $limit ) );
180
181 $result = [
182 'processed' => 0,
183 'remane' => 0,
184 ];
185
186 if ( empty( $cf_images ) ) {
187 return $result;
188 }
189
190 foreach ( $cf_images as $cf_image ) {
191 $cf_model = new WRIO_Folder_Image( $cf_image->object_id, $cf_image );
192
193 $restored = $cf_model->restore();
194
195 if ( ! is_wp_error( $restored ) ) {
196 $result['processed'] = $result['processed']++;
197 } else {
198 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to restore Custom Folder ID: %s as %s::%s failed with message: %s', $cf_image->object_id, get_class( 'WRIO_Folder_Image' ), 'restore()', $restored->get_error_message() ) );
199 }
200 }
201
202 $cf_sql_remane = "SELECT COUNT(*) AS remane FROM {$queue_table} WHERE `item_type` = %s AND `result_status` = %s";
203
204 $cf_image_remane = $wpdb->get_var( $wpdb->prepare( $cf_sql_remane, 'cf_image', RIO_Process_Queue::STATUS_SUCCESS ) );
205
206 if ( $cf_image_remane === null ) {
207 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to get remained number of Custom Folder by SQL: %s', $cf_sql_remane ) );
208 }
209
210 $result['remane'] = $cf_image_remane !== null ? (int) $cf_image_remane : 0;
211
212 if ( $result['remane'] === 0 ) {
213 // Should empty original/optimized size once all backups are empty
214 WRIO_Plugin::app()->updateOption( 'folders_original_size', 0 );
215 WRIO_Plugin::app()->updateOption( 'folders_optimized_size', 0 );
216
217 $custom_folders = WRIO_Custom_Folders::get_instance();
218 $folders = $custom_folders->getFolders();
219
220 if ( ! empty( $folders ) ) {
221 foreach ( $folders as $folder ) {
222 $folder->reCountOptimizedFiles();
223 }
224 $custom_folders->saveFolders();
225 }
226 }
227
228 return $result;
229 }
230
231 /**
232 * Восстанавливаем из резервной копии NextGEN
233 *
234 * @param WRIO_Image_Nextgen $nextgen_image аттачмент
235 *
236 * @return bool|WP_Error
237 */
238 public function restoreNextgen( $nextgen_image ) {
239
240 $original_file = $nextgen_image->get( 'path' );
241 $original_thumbnail_file = $nextgen_image->get( 'thumbnail_path' );
242 $backup_dir = $this->getNextgenBackupDir( $nextgen_image->get( 'gallery_meta' ) );
243
244 if ( is_wp_error( $backup_dir ) ) {
245 return $backup_dir;
246 }
247
248 $backup_file = $backup_dir . $nextgen_image->get( 'file' );
249 $backup_thumbnail_file = $backup_dir . $nextgen_image->get( 'thumbnail_file' );
250
251 if ( ! is_file( $backup_file ) ) {
252 $error_msg = sprintf( 'Unable to restore from a backup. There is no file (%s).', $backup_file );
253 WRIO_Plugin::app()->logger->error( sprintf( '%s, Nextgen image id: %s', $error_msg, $nextgen_image->get( 'id' ) ) );
254
255 return new WP_Error( 'file_not_exists', $error_msg );
256 }
257
258 // Restore original file
259 if ( ! $this->restore_file( $backup_file, $original_file ) ) {
260 return false;
261 }
262
263 // Restore thumbnail file
264 if ( ! $this->restore_file( $backup_thumbnail_file, $original_thumbnail_file ) ) {
265 return false;
266 }
267
268 return true;
269 }
270
271 /**
272 * Получает путь к папке с резервными копиями
273 *
274 * @param string $image_abs_path абсолютный путь к файлу картинки
275 *
276 * @return string
277 */
278 public function getCFBackupDir( $image_abs_path ) {
279 $backup_dir = $this->getBackupDir();
280
281 $image_abs_path = wp_normalize_path( $image_abs_path );
282 $wp_abs_path = wp_normalize_path( ABSPATH );
283
284 // Get all subfolders in which the image is stored.
285 // This is necessary to create an alternate subfolders
286 // in directory where they are stored in backups.
287 $subfolders = str_replace( $wp_abs_path, '', dirname( $image_abs_path ) );
288
289 $backup_dir .= self::CF_BACKUP_DIR_NAME . '/' . $subfolders;
290
291 if ( ! is_dir( $backup_dir ) ) {
292 $backup_dir = $this->mkdir( $backup_dir );
293
294 if ( is_wp_error( $backup_dir ) ) {
295 return $backup_dir;
296 }
297 }
298
299 return trailingslashit( $backup_dir );
300 }
301
302 /**
303 * Делаем резервную копию Custom Folder Image
304 *
305 * @param WRIO_Folder_Image $folder_image Custom Folder Image
306 *
307 * @return bool|WP_Error
308 */
309 public function backupCFImage( $folder_image ) {
310 $backup_origin_images = WRIO_Plugin::app()->getPopulateOption( 'backup_origin_images', false );
311
312 if ( ! $backup_origin_images ) {
313 return false; // если бекап не требуется
314 }
315
316 $original_file = $folder_image->get( 'path' );
317 $backup_dir = $this->getCFBackupDir( $original_file );
318
319 if ( is_wp_error( $backup_dir ) ) {
320 return $backup_dir;
321 }
322
323 $backup_file = $backup_dir . wp_basename( $original_file );
324
325 if ( is_file( $original_file ) ) {
326 if ( ! @copy( $original_file, $backup_file ) ) {
327 WRIO_Plugin::app()->logger->error( sprintf( 'Failed to swap original file %s with %s as copy() failed', $backup_file, $original_file ) );
328
329 return false;
330 }
331 }
332
333 return true;
334 }
335
336 /**
337 * Восстанавливаем из резервной копии Custom Folder Image
338 *
339 * @param WRIO_Folder_Image $folder_image Custom Folder Image
340 *
341 * @return bool|WP_Error
342 */
343 public function restoreCFImage( $folder_image ) {
344
345 $original_file = $folder_image->get( 'path' );
346 $backup_dir = $this->getCFBackupDir( $original_file );
347
348 if ( is_wp_error( $backup_dir ) ) {
349 return $backup_dir;
350 }
351
352 $backup_file = $backup_dir . wp_basename( $original_file );
353
354 if ( ! $this->restore_file( $backup_file, $original_file ) ) {
355 return false;
356 }
357
358 return true;
359 }
360 }
361