C:\xampp\htdocs\landing\wp-content\plugins\imagify\classes\Job\MediaOptimization.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<?php
namespace Imagify\Job;

use 
Imagify\Media\MediaInterface;
use 
Imagify\Optimization\File;
use 
Imagify\Optimization\Process\ProcessInterface;

defined'ABSPATH' ) || die( 'Cheatin’ uh?' );

/**
 * Job class for media optimization.
 *
 * @since  1.9
 * @author Grégory Viguier
 */
class MediaOptimization extends \Imagify_Abstract_Background_Process {

    
/**
     * Background process: the action to perform.
     *
     * @var    string
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     */
    
protected $action 'optimize_media';

    
/**
     * The optimization process instance.
     *
     * @var    ProcessInterface
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     */
    
protected $optimization_process;

    
/**
     * The single instance of the class.
     *
     * @var    object
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     */
    
protected static $_instance;

    
/**
     * Handle job logic.
     *
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     *
     * @param array $item {
     *     The data to use for this job.
     *
     *     @type string $task               The task to perform. Optional: set it only if you know what you’re doing.
     *     @type int    $id                 The media ID.
     *     @type array  $sizes              An array of media sizes (strings). Use "full" for the size of the main file.
     *     @type array  $sizes_done         Used internally to store the media sizes that have been processed.
     *     @type int    $optimization_level The optimization level. Null for the level set in the settings.
     *     @type string $process_class      The name of the process class. The class must implement ProcessInterface.
     *     @type array  $data               {
     *         Can be used to pass any data. Keep it short, don’t forget it will be stored in the database.
     *         It should contain the following though:
     *
     *         @type string $hook_suffix   Suffix used to trigger hooks before and after optimization. Should be always provided.
     *         @type bool   $delete_backup True to delete the backup file after the optimization process. This is used when a temporary backup of the original file has been created, but backup option is disabled. Default is false.
     *     }
     * }
     * @return array|bool The modified item to put back in the queue. False to remove the item from the queue.
     */
    
protected function task$item ) {
        
$item $this->validate_item$item );

        if ( ! 
$item ) {
            
// Not valid.
            
return false;
        }

        
// Launch the task.
        
$method 'task_' $item['task'];
        
$item   $this->$method$item );

        if ( 
$item['task'] ) {
            
// Next task.
            
return $item;
        }

        
// End of the queue.
        
$this->optimization_process->unlock();
        return 
false;
    }

    
/**
     * Trigger hooks before the optimization job.
     *
     * @since  1.9
     * @access private
     * @author Grégory Viguier
     *
     * @param  array $item See $this->task().
     * @return array       The item.
     */
    
private function task_before$item ) {
        if ( ! empty( 
$item['error'] ) && is_wp_error$item['error'] ) ) {
            
$wp_error $item['error'];
        } else {
            
$wp_error = new \WP_Error();
        }

        
/**
         * Fires before optimizing a media.
         * Any number of files can be optimized, not necessarily all of the media files.
         * If you want to return a WP_Error, use the existing $wp_error object.
         *
         * @since  1.9
         * @author Grégory Viguier
         *
         * @param array|\WP_Error  $data     New data to pass along the item. A \WP_Error object to stop the process.
         * @param \WP_Error        $wp_error Add errors to this object and return it to stop the process.
         * @param ProcessInterface $process  The optimization process.
         * @param array            $item     The item being processed. See $this->task().
         */
        
$data apply_filters'imagify_before_optimize', [], $wp_error$this->optimization_process$item );

        if ( 
is_wp_error$data ) ) {
            
$wp_error $data;
        } elseif ( 
$data && is_array$data ) ) {
            
$item['data'] = array_merge$data$item['data'] );
        }

        if ( 
$wp_error->get_error_codes() ) {
            
// Don't optimize if there is an error.
            
$item['task']  = 'after';
            
$item['error'] = $wp_error;
            return 
$item;
        }

        if ( empty( 
$item['data']['hook_suffix'] ) ) {
            
// Next task.
            
$item['task'] = 'optimize';
            return 
$item;
        }

        
$hook_suffix $item['data']['hook_suffix'];

        
/**
         * Fires before optimizing a media.
         * Any number of files can be optimized, not necessarily all of the media files.
         * If you want to return a WP_Error, use the existing $wp_error object.
         *
         * @since  1.9
         * @author Grégory Viguier
         *
         * @param array|\WP_Error  $data     New data to pass along the item. A \WP_Error object to stop the process.
         * @param \WP_Error        $wp_error Add errors to this object and return it to stop the process.
         * @param ProcessInterface $process  The optimization process.
         * @param array            $item     The item being processed. See $this->task().
         */
        
$data apply_filters"imagify_before_{$hook_suffix}", [], $wp_error$this->optimization_process$item );

        if ( 
is_wp_error$data ) ) {
            
$wp_error $data;
        } elseif ( 
$data && is_array$data ) ) {
            
$item['data'] = array_merge$data$item['data'] );
        }

        if ( 
$wp_error->get_error_codes() ) {
            
// Don't optimize if there is an error.
            
$item['task']  = 'after';
            
$item['error'] = $wp_error;
            return 
$item;
        }

        
// Next task.
        
$item['task'] = 'optimize';

        return 
$item;
    }

    
/**
     * Start the optimization job.
     *
     * @since  1.9
     * @access private
     * @author Grégory Viguier
     *
     * @param  array $item See $this->task().
     * @return array       The item.
     */
    
private function task_optimize$item ) {
        
// Determine which size we're going to optimize. The 'full' size must be optimized before any other.
        
if ( in_array'full'$item['sizes'], true ) ) {
            
$current_size  'full';
            
$item['sizes'] = array_diff$item['sizes'], [ 'full' ] );
        } else {
            
$current_size array_shift$item['sizes'] );
        }

        
$item['sizes_done'][] = $current_size;

        
// Optimize the file.
        
$data $this->optimization_process->optimize_size$current_size$item['optimization_level'] );

        if ( 
'full' === $current_size ) {
            if ( 
is_wp_error$data ) ) {
                
// Don't go further if there is an error.
                
$item['sizes'] = [];
                
$item['error'] = $data;

            } elseif ( 
'already_optimized' === $data['status'] ) {
                
// Status is "already_optimized", try to create webp versions only.
                
$item['sizes'] = array_filter$item['sizes'], [ $this->optimization_process'is_size_webp' ] );

            } elseif ( 
'success' !== $data['status'] ) {
                
// Don't go further if the full size has not the "success" status.
                
$item['sizes'] = [];
            }
        }

        if ( ! 
$item['sizes'] ) {
            
// No more files to optimize.
            
$item['task'] = 'after';
        }

        
// Optimize the next file or go to the next task.
        
return $item;
    }

    
/**
     * Trigger hooks after the optimization job.
     *
     * @since  1.9
     * @access private
     * @author Grégory Viguier
     *
     * @param  array $item See $this->task().
     * @return array       The item.
     */
    
private function task_after$item ) {
        if ( ! empty( 
$item['data']['delete_backup'] ) ) {
            
$this->optimization_process->delete_backup();
        }

        
/**
         * Fires after optimizing a media.
         * Any number of files can be optimized, not necessarily all of the media files.
         *
         * @since  1.9
         * @author Grégory Viguier
         *
         * @param ProcessInterface $process The optimization process.
         * @param array            $item    The item being processed. See $this->task().
         */
        
do_action'imagify_after_optimize'$this->optimization_process$item );

        if ( empty( 
$item['data']['hook_suffix'] ) ) {
            
$item['task'] = false;
            return 
$item;
        }

        
$hook_suffix $item['data']['hook_suffix'];

        
/**
         * Fires after optimizing a media.
         * Any number of files can be optimized, not necessarily all of the media files.
         *
         * @since  1.9
         * @author Grégory Viguier
         *
         * @param ProcessInterface $process The optimization process.
         * @param array            $item    The item being processed. See $this->task().
         */
        
do_action"imagify_after_{$hook_suffix}"$this->optimization_process$item );

        
$item['task'] = false;
        return 
$item;
    }

    
/**
     * Validate an item.
     * On success, the property $this->optimization_process is set.
     *
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     *
     * @param array $item See $this->task().
     * @return array|bool The item. False if invalid.
     */
    
protected function validate_item$item ) {
        
$this->optimization_process null;

        
$default = [
            
'task'               => '',
            
'id'                 => 0,
            
'sizes'              => [],
            
'sizes_done'         => [],
            
'optimization_level' => null,
            
'process_class'      => '',
            
'data'               => [],
        ];

        
$item imagify_merge_intersect$item$default );

        
// Validate some types first.
        
if ( ! is_array$item['sizes'] ) ) {
            return 
false;
        }

        if ( isset( 
$item['error'] ) && ! is_wp_error$item['error'] ) ) {
            unset( 
$item['error'] );
        }

        if ( isset( 
$item['data']['hook_suffix'] ) && ! is_string$item['data']['hook_suffix'] ) ) {
            unset( 
$item['data']['hook_suffix'] );
        }

        
$item['id']                 = (int) $item['id'];
        
$item['optimization_level'] = $this->sanitize_optimization_level$item['optimization_level'] );

        if ( ! 
$item['id'] || ! $item['process_class'] ) {
            return 
false;
        }

        
// Process.
        
$item['process_class'] = '\\' ltrim$item['process_class'], '\\' );

        if ( ! 
class_exists$item['process_class'] ) ) {
            return 
false;
        }

        
$process $this->get_process$item );

        if ( ! 
$process ) {
            return 
false;
        }

        
$this->optimization_process $process;

        
// Validate the current task.
        
if ( empty( $item['task'] ) ) {
            
$item['task'] = 'before';
        }

        if ( ! 
$item['task'] || ! method_exists$this'task_' $item['task'] ) ) {
            return 
false;
        }

        if ( ! 
$item['sizes'] && 'after' !== $item['task'] ) {
            
// Allow to have no sizes, but only after the optimize task is complete.
            
return false;
        }

        if ( ! isset( 
$item['sizes_done'] ) || ! is_array$item['sizes_done'] ) ) {
            
$item['sizes_done'] = [];
        }

        return 
$item;
    }

    
/**
     * Get the process instance.
     *
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     *
     * @param array $item             See $this->task().
     * @return ProcessInterface|bool The instance object on success. False on failure.
     */
    
protected function get_process$item ) {
        
$process_class $item['process_class'];
        
$process       = new $process_class$item['id'] );

        if ( ! 
$process instanceof ProcessInterface || ! $process->is_valid() ) {
            return 
false;
        }

        return 
$process;
    }

    
/**
     * Sanitize and validate an optimization level.
     * If not provided (false, null), fallback to the level set in the plugin's settings.
     *
     * @since  1.9
     * @access protected
     * @author Grégory Viguier
     *
     * @param  mixed $optimization_level The optimization level.
     * @return int
     */
    
protected function sanitize_optimization_level$optimization_level ) {
        if ( ! 
is_numeric$optimization_level ) ) {
            return 
get_imagify_option'optimization_level' );
        }

        return \
Imagify_Options::get_instance()->sanitize_and_validate'optimization_level'$optimization_level );
    }
}
x

Windows NT KPTV 6.2 build 9200 (Windows Server 2012 Datacenter Edition) i586