PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.8.0
Tutor LMS – eLearning and online course solution v3.8.0
4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / migrations / BatchProcessor.php
tutor / migrations Last commit date
BatchProcessor.php 10 months ago Migration.php 10 months ago QuizAttemptMigrator.php 10 months ago
BatchProcessor.php
298 lines
1 <?php
2 /**
3 * Class to handle process large amount of data with batch.
4 *
5 * @package Tutor
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 3.8.0
9 */
10
11 namespace Tutor\Migrations;
12
13 /**
14 * Class BatchProcessor
15 *
16 * @since 3.8.0
17 */
18 abstract class BatchProcessor {
19 /**
20 * Batch size.
21 *
22 * @since 3.8.0
23 *
24 * @var int
25 */
26 protected $batch_size;
27
28 /**
29 * Schedule interval
30 *
31 * @since 3.8.0
32 *
33 * @var int
34 */
35 protected $schedule_interval;
36
37 /**
38 * Progress option name to keep track of each process status.
39 *
40 * @since 3.8.0
41 *
42 * @var string
43 */
44 protected $progress_option;
45
46 /**
47 * Manage child class as singleton behavior.
48 *
49 * @since 3.8.0
50 *
51 * @var object
52 */
53 protected static $instance = null;
54
55 /**
56 * Action name to invoke wp-cron.
57 *
58 * @since 3.8.0
59 *
60 * @var string
61 */
62 protected $action;
63
64 /**
65 * Name of the process.
66 *
67 * @since 3.8.0
68 *
69 * @var string
70 */
71 protected $name;
72
73 /**
74 * Constructor.
75 *
76 * @since 3.8.0
77 *
78 * @throws \Exception If action is not set.
79 */
80 protected function __construct() {
81 if ( empty( $this->action ) ) {
82 throw new \Exception( 'Action property must be defined in the subclass.' );
83 }
84
85 $this->progress_option = "tutor_batch_processor_{$this->action}";
86 add_action( $this->action, array( $this, 'process_batch' ) );
87 }
88
89 /**
90 * Get child class instance.
91 *
92 * @since 3.8.0
93 *
94 * @return object
95 */
96 public static function instance() {
97 if ( null === static::$instance ) {
98 static::$instance = new static();
99 }
100 return static::$instance;
101 }
102
103 /**
104 * Get items to process.
105 * Must be implemented in child class.
106 *
107 * @since 3.8.0
108 *
109 * @param int $offset offset.
110 * @param int $limit limit.
111 *
112 * @return array
113 */
114 abstract protected function get_items( $offset, $limit) : array;
115
116 /**
117 * Get total items to process.
118 * Must be implemented in child class.
119 *
120 * @since 3.8.0
121 *
122 * @return int
123 */
124 abstract protected function get_total_items() : int;
125
126 /**
127 * Process a single item.
128 * Must be implemented in child class.
129 *
130 * @since 3.8.0
131 *
132 * @param mixed $item item.
133 *
134 * @return void
135 */
136 abstract protected function process_item( $item) : void;
137
138 /**
139 * Schedule the batch processing.
140 *
141 * This method checks if the action is already scheduled, and if not, it schedules a single event
142 * to trigger the batch processing after the specified interval.
143 *
144 * @since 3.8.0
145 *
146 * @return void
147 */
148 public function schedule() {
149 if ( ! wp_next_scheduled( $this->action ) ) {
150 wp_schedule_single_event( time() + $this->schedule_interval, $this->action );
151 }
152 }
153
154 /**
155 * Process a batch of items.
156 *
157 * This method retrieves a batch of items based on the current offset and batch size,
158 * processes each item, updates the progress, and schedules the next batch processing.
159 *
160 * @since 3.8.0
161 *
162 * @return void
163 */
164 public function process_batch() {
165 $progress = get_option(
166 $this->progress_option,
167 array(
168 'name' => $this->name,
169 'started_at' => gmdate( 'Y-m-d H:i:s' ),
170 'completed_at' => null,
171 'offset' => 0,
172 'completed' => false,
173 'total_items' => null,
174 'total_batch' => null,
175 'per_batch' => $this->batch_size,
176 'current_batch' => 1,
177 )
178 );
179
180 if ( $progress['completed'] ) {
181 return;
182 }
183
184 // Set total_items and total_batch if not already set.
185 if ( is_null( $progress['total_items'] ) ) {
186 $progress['total_items'] = $this->get_total_items();
187 $progress['total_batch'] = (int) ceil( $progress['total_items'] / $progress['per_batch'] );
188 }
189
190 $items = $this->get_items( $progress['offset'], $this->batch_size );
191
192 if ( empty( $items ) ) {
193 $this->mark_complete();
194 return;
195 }
196
197 foreach ( $items as $item ) {
198 $this->process_item( $item );
199 }
200
201 $progress['offset'] += count( $items );
202 $progress['current_batch'] = (int) ceil( $progress['offset'] / $progress['per_batch'] );
203 update_option( $this->progress_option, $progress );
204
205 wp_schedule_single_event( time() + $this->schedule_interval, $this->action );
206 }
207
208 /**
209 * Mark the batch processing as complete.
210 *
211 * This method updates the progress option to indicate that the batch processing is complete
212 * and calls the optional `on_complete` method for any additional actions needed upon completion.
213 *
214 * @since 3.8.0
215 *
216 * @return void
217 */
218 protected function mark_complete() {
219 $data = wp_parse_args(
220 array(
221 'offset' => 0,
222 'completed' => true,
223 'completed_at' => gmdate( 'Y-m-d H:i:s' ),
224 ),
225 $this->get_stats()
226 );
227
228 update_option( $this->progress_option, $data );
229
230 $this->on_complete();
231 }
232
233 /**
234 * Optional method to override in child classes to perform actions when the batch processing is complete.
235 *
236 * @since 3.8.0
237 *
238 * @return void
239 */
240 protected function on_complete() {}
241
242 /**
243 * Check is complete.
244 *
245 * @since 3.8.0
246 *
247 * @return boolean
248 */
249 public function is_completed(): bool {
250 $progress = get_option( $this->progress_option, array() );
251 return ! empty( $progress['completed'] );
252 }
253
254 /**
255 * Get the progress option name.
256 *
257 * @since 3.8.0
258 *
259 * @return string
260 */
261 public function get_progress_option_name() {
262 return $this->progress_option;
263 }
264
265 /**
266 * Get the progress stats.
267 *
268 * @since 3.8.0
269 *
270 * @return array
271 */
272 public function get_stats(): array {
273 $progress = get_option( $this->progress_option, array() );
274 return wp_parse_args(
275 $progress,
276 array(
277 'offset' => 0,
278 'completed' => false,
279 'total_items' => 0,
280 'total_batch' => 0,
281 'per_batch' => $this->batch_size,
282 'current_batch' => 1,
283 )
284 );
285 }
286
287 /**
288 * Reset the progress option.
289 *
290 * @since 3.8.0
291 *
292 * @return void
293 */
294 public function reset() {
295 delete_option( $this->progress_option );
296 }
297 }
298