/
class-fw-ext-backups-task-type-image-sizes-restore.php
137 lines (117 loc) · 3.94 KB
/
class-fw-ext-backups-task-type-image-sizes-restore.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php if (!defined('FW')) die('Forbidden');
class FW_Ext_Backups_Task_Type_Image_Sizes_Restore extends FW_Ext_Backups_Task_Type {
public function get_type() {
return 'image-sizes-restore';
}
public function get_title(array $args = array(), array $state = array()) {
return __('Image Sizes Restore', 'fw') .(
empty($state)
? ''
: ' '. sprintf(__('(%d of %d)', 'fw'), $state['processed_images'], $state['total_images'])
);
}
public function get_custom_timeout(array $args, array $state = array()) {
/** @var FW_Extension_Backups $backups */
$backups = fw_ext( 'backups' );
/**
* Use a small value because problems with this step are quite often
* and it is frustrating to wait 10+ minutes just to see the Timed Out error (better to see it earlier)
*/
return $backups->get_task_step_execution_threshold() - 1;
}
/**
* {@inheritdoc}
* @param array $args
*/
public function execute(array $args, array $state = array()) {
/** @var WPDB $wpdb */
global $wpdb;
if ( empty( $state ) ) {
$state = array(
// The attachment at which the execution stopped and will continue in next request
'attachment_id' => 0,
// Process one image size per request
'pending_sizes' => array(),
// Collect the processed sizes and use this value as attachment meta to prevent regenerating all sizes
'processed_sizes' => array(),
// Count the processed images
'processed_images' => 0,
);
if ($state['total_images'] = $wpdb->get_col(
$wpdb->prepare(
"SELECT COUNT(1) as total_images FROM {$wpdb->posts}"
." WHERE post_type = 'attachment' AND post_mime_type LIKE %s"
." LIMIT 1",
$wpdb->esc_like( 'image/' ) . '%'
),
0
)) {
$state['total_images'] = array_pop($state['total_images']);
} else {
return new WP_Error(
'total_images_fail',
__('Cannot get total images count', 'fw')
);
}
}
/** @var FW_Extension_Backups $backups */
$backups = fw_ext( 'backups' );
$max_time = time() + $backups->get_timeout(-10); // -SECONDS that one image size can take on a very slow server
while (time() < $max_time) {
if ( $attachment_id = $wpdb->get_col(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}"
." WHERE post_type = 'attachment' AND post_mime_type LIKE %s AND ID > %d"
." ORDER BY ID"
." LIMIT 1",
$wpdb->esc_like( 'image/' ) . '%', $state['attachment_id']
),
0
) ) {
$attachment_id = array_pop($attachment_id);
} else {
return true;
}
if ( $file_exists = file_exists( $file = get_attached_file( $attachment_id ) ) ) {
if (empty($state['pending_sizes'])) {
$state['pending_sizes'] = get_intermediate_image_sizes();
$state['processed_sizes'] = array();
}
while (time() < $max_time && !empty($state['pending_sizes'])) {
{
$this->current_size = array_shift($state['pending_sizes']);
add_filter('intermediate_image_sizes', array($this, '_filter_image_sizes'));
$meta = wp_generate_attachment_metadata($attachment_id, $file);
$this->current_size = '';
remove_filter('intermediate_image_sizes', array($this, '_filter_image_sizes'));
}
$state['processed_sizes'] = array_merge($state['processed_sizes'], $meta['sizes']);
}
if (isset($meta)) {
$meta['sizes'] = $state['processed_sizes'];
wp_update_attachment_metadata($attachment_id, $meta);
unset($meta);
}
}
if (empty($state['pending_sizes']) || !$file_exists) { // Proceed to next attachment
$state['attachment_id'] = $attachment_id;
$state['processed_sizes'] = $state['pending_sizes'] = array();
++$state['processed_images'];
}
}
return $state;
}
private $current_size = '';
/**
* Leave only one image size so it will be generated fast and will prevent timeout
* @param array $sizes
* @return array
*/
public function _filter_image_sizes($sizes) {
if ($this->current_size) {
return array($this->current_size);
} else {
return $sizes;
}
}
}