PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / trunk
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell vtrunk
3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 2.8.17 2.8.18 All 259 releases
wpfunnels / admin / BatchProcessing / BatchProcessingController.php

BatchProcessingController.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell trunk, at admin/BatchProcessing/BatchProcessingController.php

233 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPFunnels\Admin\BatchProcessing;
4
5
6 /**
7 * This class handles batch processing of data in a deferred way, abstracting the scheduling and error handling.
8 *
9 * Usage:
10 * 1. Create a class that implements BatchProcessorInterface.
11 * 2. Invoke the 'enqueue_processor' method with the processor class name when there's data to process.
12 *
13 * Processing will be done in batches via scheduled actions. Processors will be dequeued once they finish processing.
14 * Failed batches will be retried.
15 *
16 * Credit: Inspired by WooCommerce's BatchProcessingController.
17 *
18 * @package WPFunnels\Admin\BatchProcessing
19 * @since 3.5.0
20 */
21 class BatchProcessingController {
22
23 /**
24 * Action name for scheduling pending batch processes.
25 */
26 const WPFUNNELS_SCHEDULE_PENDING_ACTION_NAME = 'wpfunnels_schedule_pending_batch_processes';
27
28 /**
29 * Action name for processing a single batch.
30 */
31 const WPFUNNELS_SINGLE_BATCH_ACTION_NAME = 'wpfunnels_batch_process';
32
33
34 /**
35 * BatchProcessingController constructor.
36 *
37 * Initializes the batch processing controller and sets up the necessary actions.
38 *
39 * @since 3.5.0
40 */
41 public function __construct() {
42 add_action(
43 self::WPFUNNELS_SCHEDULE_PENDING_ACTION_NAME,
44 function () {
45 $this->handle_pending_actions();
46 }
47 );
48
49 add_action(
50 self::WPFUNNELS_SINGLE_BATCH_ACTION_NAME,
51 function ( $processor_class_name ) {
52 $this->process_next_batch_for_single_processor( $processor_class_name );
53 }
54 );
55 }
56
57
58 /**
59 * Enqueue a processor for batch processing.
60 *
61 * @param string $key The key for the processor.
62 * @param string $instance_class_name The class name of the processor instance.
63 *
64 * @since 3.5.0
65 */
66 public function enqueue_processor( $key, $instance_class_name ) {
67 $enqueued_processes = get_option( 'wpfunnels_pending_batch_processes', array() );
68 if ( ! in_array( $key, array_keys( $enqueued_processes ), true ) ) {
69 $pending_updates[$key] = $instance_class_name;
70 $this->set_enqueued_processors( $pending_updates );
71 }
72 $this->schedule_action();
73 }
74
75
76
77 /**
78 * Dequeue a processor from batch processing.
79 *
80 * @param string $processor_class_name The class name of the processor instance.
81 *
82 * @since 3.5.0
83 */
84 private function dequeue_processor( $processor_class_name ) {
85 $pending_processes = $this->get_enqueued_processors();
86 if ( in_array( $processor_class_name, $pending_processes, true ) ) {
87 $pending_processes = array_diff( $pending_processes, array( $processor_class_name ) );
88 $this->set_enqueued_processors( $pending_processes );
89 }
90 }
91
92
93 /**
94 * Set the enqueued processors.
95 *
96 * @param array $pending_updates The array of pending updates.
97 *
98 * @since 3.5.0
99 */
100 public function set_enqueued_processors( $pending_updates ) {
101 update_option( 'wpfunnels_pending_batch_processes', $pending_updates, false );
102 }
103
104
105 /**
106 * Get the enqueued processors.
107 *
108 * @return array The array of enqueued processors.
109 *
110 * @since 3.5.0
111 */
112 public function get_enqueued_processors() {
113 return get_option('wpfunnels_pending_batch_processes', array());
114 }
115
116
117 /**
118 * Schedule the action for processing pending batch processes.
119 *
120 * @since 3.5.0
121 */
122 public function schedule_action() {
123 $time = time();
124 if ( ! as_has_scheduled_action( self::WPFUNNELS_SCHEDULE_PENDING_ACTION_NAME ) ) {
125 as_schedule_single_action(
126 $time,
127 self::WPFUNNELS_SCHEDULE_PENDING_ACTION_NAME,
128 array(),
129 'wpfunnels_batch_processes',
130 true
131 );
132 }
133 }
134
135
136 /**
137 * Check if a processor is scheduled.
138 *
139 * @param string $processor_class_name The class name of the processor instance.
140 * @return bool True if the processor is scheduled, false otherwise.
141 *
142 * @since 3.5.0
143 */
144 public function is_scheduled( $processor_class_name ) {
145 return as_has_scheduled_action( self::WPFUNNELS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
146 }
147
148
149
150 /**
151 * Check if a processor is scheduled.
152 *
153 * @param string $processor_class_name The class name of the processor instance.
154 * @return bool True if the processor is scheduled, false otherwise.
155 *
156 * @since 3.5.0
157 */
158 private function schedule_batch_processing( $processor_class_name ) {
159 as_schedule_single_action( time(), self::WPFUNNELS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
160 }
161
162
163 /**
164 * Check if a processor is enqueued.
165 *
166 * @param string $processor_class_name The class name of the processor instance.
167 * @return bool True if the processor is enqueued, false otherwise.
168 *
169 * @since 3.5.0
170 */
171 private function is_enqueued( $processor_class_name ) {
172 return in_array( $processor_class_name, $this->get_enqueued_processors(), true );
173 }
174
175
176 /**
177 * Get the instance of a processor.
178 *
179 * @param string $processor_class_name The class name of the processor instance.
180 * @return mixed The processor instance or false if the class does not exist.
181 *
182 * @since 3.5.0
183 */
184 private function get_processor_instance( $processor_class_name ) {
185 if ( class_exists( $processor_class_name ) ) {
186 $processor = new $processor_class_name();
187 return $processor;
188 }
189 return false;
190 }
191
192
193 /**
194 * Handle pending actions by scheduling batch processing for each enqueued processor.
195 *
196 * @since 3.5.0
197 */
198 private function handle_pending_actions() {
199 $pending_processes = $this->get_enqueued_processors();
200 if ( empty( $pending_processes ) ) {
201 return;
202 }
203 foreach ( $pending_processes as $processor_class_name ) {
204 if ( ! $this->is_scheduled( $processor_class_name ) ) {
205 $this->schedule_batch_processing( $processor_class_name );
206 }
207 }
208 $this->schedule_action();
209 }
210
211
212 /**
213 * Process the next batch for a single processor.
214 *
215 * @param string $processor_class_name The class name of the processor instance.
216 *
217 * @since 3.5.0
218 */
219 private function process_next_batch_for_single_processor( $processor_class_name ) {
220 if ( ! $this->is_enqueued( $processor_class_name ) ) {
221 return;
222 }
223 $batch_processor = $this->get_processor_instance( $processor_class_name );
224 $batch_processor->process_batch();
225 $still_pending = $batch_processor->should_enqueue_migration_instance();
226 if ( $still_pending ) {
227 $this->schedule_batch_processing( $processor_class_name );
228 } else {
229 $this->dequeue_processor( $processor_class_name );
230 }
231 }
232 }
233