PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.3
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.3
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / vendor / team-updraft / common-libs / src / updraft-tasks / class-updraft-task-manager.php

class-updraft-task-manager.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.3, at vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task-manager.php

388 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A task manager that locks and processes the task queue
4 */
5
6 if (!defined('ABSPATH')) die('Access denied.');
7
8 if (!class_exists('Updraft_Task_Manager_1_3')) :
9
10 abstract class Updraft_Task_Manager_1_3 {
11
12 protected $loggers;
13
14 public $commands;
15
16 private $queue_semaphore;
17
18 /**
19 * Set this to the number of seconds for the lock timeout, or 0 to not use a lock
20 */
21 protected $use_per_task_lock = 0;
22
23 /**
24 * The Task Manager constructor
25 */
26 public function __construct() {
27
28 if (!class_exists('Updraft_Task_1_2')) require_once('class-updraft-task.php');
29 if (!class_exists('Updraft_Task_Manager_Commands_1_0')) require_once('class-updraft-task-manager-commands.php');
30 if (!class_exists('Updraft_Semaphore_3_0')) require_once(dirname(__FILE__).'/../updraft-semaphore/class-updraft-semaphore.php');
31 if (!class_exists('Updraft_Tasks_Activation')) require_once(dirname(__FILE__).'/class-updraft-tasks-activation.php');
32
33 $this->commands = new Updraft_Task_Manager_Commands_1_0($this);
34
35 add_action('wp_ajax_updraft_taskmanager_ajax', array($this, 'updraft_taskmanager_ajax'));
36
37 do_action('updraft_task_manager_loaded', $this);
38 }
39
40 /**
41 * The Task Manager AJAX handler
42 */
43 public function updraft_taskmanager_ajax() {
44
45 $nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce'];
46
47 if (!wp_verify_nonce($nonce, 'updraft-task-manager-ajax-nonce') || empty($_REQUEST['subaction']))
48 die('Security check failed');
49
50 $subaction = $_REQUEST['subaction'];
51
52 $allowed_commands = Updraft_Task_Manager_Commands_1_0::get_allowed_ajax_commands();
53
54 if (in_array($subaction, $allowed_commands)) {
55
56 if (isset($_REQUEST['action_data']))
57 $data = $_REQUEST['action_data'];
58
59 $results = call_user_func(array($this->commands, $subaction), $data);
60
61 if (is_wp_error($results)) {
62 $results = array(
63 'result' => false,
64 'error_code' => $results->get_error_code(),
65 'error_message' => $results->get_error_message(),
66 'error_data' => $results->get_error_data(),
67 );
68 }
69
70 echo json_encode($results);
71 } else {
72 echo json_encode("{'error' : 'No such command found'}");
73 }
74 die;
75 }
76
77 /**
78 * Process a single task in the queue
79 *
80 * @param int|Updraft_Task - $task Task ID or Updraft_Task object.
81 * @return boolean|WP_Error - status of task or error if task not found
82 */
83 public function process_task($task) {
84
85 if (!is_a($task, 'Updraft_Task_1_2')) {
86 $task_id = (int) $task;
87 $task = $this->get_task_instance($task_id);
88 }
89
90 if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid');
91
92 return $task->attempt(apply_filters('updraft_task_lock_for', $this->use_per_task_lock, $this));
93
94 }
95
96 /**
97 * Gets a list of all tasks that matches the $status flag
98 *
99 * @param int|Updraft_Task - $task Task ID or Updraft_Task object.
100 * @return String|WP_Error - status of task or error if task not found.
101 */
102 public function get_task_status($task) {
103
104 if (!($task instanceof Updraft_Task_1_2)) {
105 $task_id = (int) $task;
106 $task = $this->get_task_instance($task_id);
107 }
108
109 if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid');
110
111 return $task->get_status();
112 }
113
114 /**
115 * Ends a given task
116 *
117 * @param int|Updraft_Task - $task Task ID or Updraft_Task object.
118 * @return boolean|WP_Error - Status of the operation or error if task not found.
119 */
120 public function end_task($task) {
121
122 if (!($task instanceof Updraft_Task_1_2)) {
123 $task_id = (int) $task;
124 $task = $this->get_task_instance($task_id);
125 }
126
127 if (!$task) return new WP_Error('id_invalid', 'Task not found or ID is invalid');
128
129 return $task->complete();
130 }
131
132 /**
133 * Process a the queue of a specifed task type
134 *
135 * @param string $type queue type to process
136 * @return bool true on success, false otherwise
137 */
138 public function process_queue($type) {
139
140 $task_list = $this->get_active_tasks($type);
141 $total = is_array($task_list) ? count($task_list) : 0;
142
143 if (1 > $total) {
144 $this->log(sprintf('The queue for tasks of type "%s" is empty. Aborting!', $type));
145 return true;
146 } else {
147 $this->log(sprintf('A total of %d tasks of type %s found and will be processed in this iteration', $total, $type));
148 }
149
150 $this->queue_semaphore = new Updraft_Semaphore_3_0($type);
151
152 // Prevent PHP warning which trigger from semaphore class set_loggers method if $this->loggers is empty
153 if (!empty($this->loggers)) {
154 $this->queue_semaphore->set_loggers($this->loggers);
155 }
156
157 if (!$this->queue_semaphore->lock()) {
158
159 $this->log(sprintf('Failed to gain semaphore lock (%s) - another process is already processing the queue - aborting (if this is wrong - i.e. if the other process crashed without removing the lock, then another can be started after 1 minute', $type));
160
161 return false;
162 }
163
164 $done = 0;
165 foreach ($task_list as $task) {
166 $this->process_task($task);
167 $done++;
168 /**
169 * Filters if the queue should be interrupted. Used after processing each task.
170 *
171 * @param boolean $interrupt_queue - If the queue should be interrupted. Default to FALSE
172 * @param object $task - The current task object
173 * @param object $task_manager - The task manager instance
174 */
175 if (apply_filters('updraft_interrupt_tasks_queue_'.$type, false, $task, $this)) {
176 break;
177 }
178 }
179
180 $this->queue_semaphore->release();
181 $this->log(sprintf('Successfully processed the queue (%s). %d tasks were processed out of %d.', $type, $done, $total));
182 $this->queue_semaphore->delete();
183
184 return $done == $total;
185 }
186
187 /**
188 * Cleans out all complete tasks from the DB.
189 *
190 * @param String $type type of the task
191 */
192 public function clean_up_old_tasks($type) {
193 $completed_tasks = $this->get_completed_tasks($type);
194
195 if (!$completed_tasks) return false;
196
197 $this->log(sprintf('Cleaning up tasks of type (%s). A total of %d tasks will be deleted.', $type, count($completed_tasks)));
198
199 foreach ($completed_tasks as $task) {
200 $task->delete_meta();
201 $task->delete();
202 }
203
204 return true;
205 }
206
207 /**
208 * Delete all tasks from queue.
209 *
210 * @param string $type
211 *
212 * @return boolean|integer Number of rows deleted, or (boolean)false upon error
213 */
214 public function delete_tasks($task_type) {
215 global $wpdb;
216
217 $sql = "DELETE t, tm FROM `{$wpdb->base_prefix}tm_tasks` t LEFT JOIN `{$wpdb->base_prefix}tm_taskmeta` tm ON t.id = tm.task_id WHERE t.type = '{$task_type}'";
218
219 return $wpdb->query($sql);
220 }
221
222 /**
223 * Get count of completed and all tasks.
224 *
225 * @return array - [ ['complete_tasks' => , 'all_tasks' => ] ]
226 */
227 public function get_status($task_type) {
228 global $wpdb;
229
230 $query = $wpdb->prepare(
231 "SELECT complete_tasks, all_tasks FROM (SELECT COUNT(*) AS complete_tasks FROM {$wpdb->base_prefix}tm_tasks WHERE `type` = %s AND `status` = %s) a, (SELECT COUNT(*) AS all_tasks FROM {$wpdb->base_prefix}tm_tasks WHERE `type` = %s) b",
232 array(
233 $task_type,
234 'complete',
235 $task_type,
236 )
237 );
238
239 $status = $wpdb->get_row($query, ARRAY_A);
240
241 if (empty($status)) {
242 $status = array(
243 'complete_tasks' => 0,
244 'all_tasks' => 0,
245 );
246 }
247
248 return $status;
249 }
250
251 /**
252 * Fetches a list of all active tasks
253 *
254 * @param String $type type of the task
255 * @return Mixed - array of Task ojects or NULL if none found
256 */
257 public function get_active_tasks($type) {
258 return $this->get_tasks('active', $type);
259 }
260
261 /**
262 * Gets a list of all completed tasks
263 *
264 * @param String $type type of the task
265 * @return Mixed - array of Task ojects or NULL if none found
266 */
267 public function get_completed_tasks($type) {
268 return $this->get_tasks('complete', $type);
269 }
270
271 /**
272 * Gets a list of all tasks that matches the $status flag
273 *
274 * @param String $status - status of tasks to return, defaults to all tasks
275 * @param String $type - type of task
276 *
277 * @return Mixed - array of Task objects or NULL if none found
278 */
279 public function get_tasks($status, $type) {
280 global $wpdb;
281
282 $tasks = array();
283
284 if (array_key_exists($status, Updraft_Task_1_2::get_allowed_statuses())) {
285 $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE status = %s AND type = %s", $status, $type);
286 } else {
287 $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE type = %s", $type);
288 }
289
290 $_tasks = $wpdb->get_results($sql);
291
292 if (!$_tasks) {
293 // if we got an error then check if task manager tables are in the database
294 // and recreate them if needed.
295 if ($wpdb->last_error) {
296 Updraft_Tasks_Activation::reinstall_if_needed();
297 }
298 return;
299 }
300
301
302 foreach ($_tasks as $_task) {
303 $task = $this->get_task_instance($_task->id);
304 if ($task) array_push($tasks, $task);
305 }
306
307 return $tasks;
308 }
309
310 /**
311 * Retrieve the task instance using its ID
312 *
313 * @access public
314 *
315 * @global wpdb $wpdb WordPress database abstraction object.
316 *
317 * @param int $task_id Task ID.
318 * @return Task|Boolean Task object, false otherwise.
319 */
320 public function get_task_instance($task_id) {
321 global $wpdb;
322
323 $task_id = (int) $task_id;
324 if (!$task_id) return false;
325
326 $sql = $wpdb->prepare("SELECT * FROM {$wpdb->base_prefix}tm_tasks WHERE id = %d LIMIT 1", $task_id);
327 $_task = $wpdb->get_row($sql);
328
329 if (!$_task)
330 return false;
331
332 $class_identifier = $_task->class_identifier;
333
334 if (class_exists($class_identifier))
335 $task_instance = new $class_identifier($_task);
336 $task_instance->set_loggers($this->loggers);
337 return $task_instance;
338
339 return false;
340 }
341
342 /**
343 * Sets the logger for this instance.
344 *
345 * @param array $loggers - the loggers for this task
346 */
347 public function set_loggers($loggers) {
348 foreach ($loggers as $logger) {
349 $this->add_logger($logger);
350 }
351 }
352
353 /**
354 * Add a logger to loggers list
355 *
356 * @param Object $logger - a logger for the instance
357 */
358 public function add_logger($logger) {
359 $this->loggers[] = $logger;
360 }
361
362 /**
363 * Return list of loggers
364 *
365 * @return array
366 */
367 public function get_loggers() {
368 return $this->loggers;
369 }
370
371 /**
372 * Captures and logs any interesting messages
373 *
374 * @param String $message - the error message
375 * @param String $error_type - the error type
376 */
377 public function log($message, $error_type = 'info') {
378 if (isset($this->loggers)) {
379 foreach ($this->loggers as $logger) {
380 $logger->log($message, $error_type);
381 }
382 }
383 }
384
385 }
386
387 endif;
388