PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.1.2
JetFormBuilder — Dynamic Blocks Form Builder v3.1.2
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / actions / action-handler.php
jetformbuilder / includes / actions Last commit date
conditions 2 years ago events 2 years ago methods 2 years ago types 2 years ago action-handler.php 2 years ago action-localize.php 2 years ago actions-tools.php 2 years ago events-list.php 2 years ago events-manager.php 2 years ago legacy-request-data.php 2 years ago manager.php 2 years ago send-email-hooks.php 2 years ago
action-handler.php
568 lines
1 <?php
2
3 namespace Jet_Form_Builder\Actions;
4
5 // If this file is called directly, abort.
6 use Jet_Form_Builder\Actions\Events\Base_Executor;
7 use Jet_Form_Builder\Actions\Types\Base;
8 use Jet_Form_Builder\Exceptions\Action_Exception;
9 use Jet_Form_Builder\Exceptions\Condition_Exception;
10 use Jet_Form_Builder\Exceptions\Repository_Exception;
11 use Jet_Form_Builder\Plugin;
12 use Jet_Form_Builder\Actions\Conditions\Condition_Manager;
13
14 if ( ! defined( 'WPINC' ) ) {
15 die;
16 }
17
18 /**
19 * Define Actions handler class class
20 */
21 class Action_Handler {
22
23 public $form_id = null;
24
25 /**
26 * @deprecated 3.1.0 Use jet_fb_context() instead
27 * @var Legacy_Request_Data
28 */
29 public $request_data = array();
30 /**
31 * @var Base[]
32 */
33 public $form_actions = array();
34 public $is_ajax = false;
35 private $form_conditions = array();
36 private $form_events = array();
37
38 public $response_data = array();
39
40 public $context = array();
41
42 /** @var bool|int Current Action ID */
43 public $current_position = false;
44
45 /** @var string */
46 public $current_flow_handler = '';
47
48 /**
49 * @var array Action IDs that were executed without errors
50 */
51 protected $passed = array();
52
53 /**
54 * @var array Action IDs that were skipped due to a condition not matching
55 */
56 protected $skipped = array();
57
58 public function __construct() {
59 $this->request_data = new Legacy_Request_Data();
60 }
61
62 public function get_form_id() {
63 return (int) $this->form_id;
64 }
65
66 /**
67 * @param $form_id
68 *
69 * @return Action_Handler
70 */
71 public function set_form_id( $form_id ) {
72 if ( ! $form_id || $form_id === $this->form_id ) {
73 return $this;
74 }
75 $this->form_id = $form_id;
76 $this->set_form_actions();
77
78 return $this;
79 }
80
81 public function add_request( $request ): Action_Handler {
82 if ( ! $this->in_loop() ) {
83 foreach ( $request as $name => $value ) {
84 jet_fb_context()->update_request( $value, $name );
85 }
86
87 return $this;
88 }
89
90 foreach ( $request as $field_name => $value ) {
91 $field_name = jet_fb_context()->get_unique_name( $field_name );
92
93 jet_fb_context()->update_request( $value, $field_name );
94 }
95
96 return $this;
97 }
98
99 /**
100 * Set form actions,
101 * which were saved in form meta
102 *
103 * @return Action_Handler
104 */
105 public function set_form_actions() {
106 $form_actions = Plugin::instance()->post_type->get_actions( $this->form_id );
107
108 foreach ( $form_actions as $form_action ) {
109 try {
110 $this->save_form_action( $form_action )->on_register_in_flow();
111 } catch ( Repository_Exception $exception ) {
112 continue;
113 }
114 }
115
116 return $this;
117 }
118
119 /**
120 * @param $form_action
121 *
122 * @return Base
123 * @throws Repository_Exception
124 */
125 private function save_form_action( $form_action ): Base {
126 $type = $form_action['type'];
127
128 if ( ! ( $form_action['is_execute'] ?? true ) ) {
129 throw new Repository_Exception( 'This action is turned off' );
130 }
131
132 $action = jet_form_builder()->actions->get_action_clone( $type );
133
134 $id = $form_action['id'];
135 $settings = $form_action['settings'][ $type ] ?? $form_action['settings'];
136
137 /**
138 * Save action settings to the class field,
139 * it allows to not send action settings
140 * in action hook
141 */
142 $action->_id = $id;
143 $action->settings = $settings;
144
145 $this->save_action( $action, $form_action );
146
147 return $action;
148 }
149
150 /**
151 * Doesn't throw an exception if there are no actions
152 *
153 * Don't call manually.
154 * Use jet_fb_events()->execute() instead.
155 *
156 * @param Base_Executor $executor
157 *
158 * @return $this
159 * @throws Action_Exception
160 */
161 public function soft_run_actions( Base_Executor $executor ): Action_Handler {
162 if ( ! count( $executor ) ) {
163 return $this;
164 }
165 $this->run_actions( $executor );
166
167 return $this;
168 }
169
170 /**
171 * Don't call manually.
172 * Use jet_fb_events()->execute() instead.
173 *
174 * @param Base_Executor $executor
175 *
176 * @throws Action_Exception
177 */
178 public function run_actions( Base_Executor $executor ) {
179 if ( ! count( $executor ) ) {
180 throw new Action_Exception( 'failed', 'Empty actions' );
181 }
182
183 foreach ( $executor as $action ) {
184 $this->process_single_action( $action );
185 }
186
187 /**
188 * End the cycle
189 */
190 $this->set_current_action( false );
191 }
192
193 public function process_single_action( Base $action ) {
194 /**
195 * Start the cycle
196 *
197 * @var int current_position
198 */
199 $this->set_current_action( $action->_id );
200
201 try {
202 /**
203 * Check conditions for action
204 */
205 $this->get_current_condition_manager()->check_all();
206 } catch ( Condition_Exception $exception ) {
207 /**
208 * We save the ID of the current action,
209 * for possible logging of form entries
210 */
211 $this->skipping_current();
212
213 return;
214 }
215
216 /**
217 * Process single action
218 */
219 $action->do_action( jet_fb_context()->resolve_request(), $this );
220
221 /**
222 * We save the ID of the current action,
223 * for possible logging of form entries
224 */
225 $this->passing_current();
226 }
227
228 /**
229 * Unregister notification by id
230 *
231 * @param $key
232 *
233 * @return Action_Handler [description]
234 */
235 public function unregister_action( $key ) {
236 if ( is_numeric( $key ) && isset( $this->form_actions[ $key ] ) ) {
237 unset( $this->form_actions[ $key ] );
238 unset( $this->form_conditions[ $key ] );
239 unset( $this->form_events[ $key ] );
240
241 return $this;
242 }
243 foreach ( $this->form_actions as $index => $action ) {
244 if ( $key === $action->get_id() ) {
245 unset( $this->form_actions[ $index ] );
246 unset( $this->form_conditions[ $index ] );
247 unset( $this->form_events[ $index ] );
248
249 return $this;
250 }
251 }
252
253 return $this;
254 }
255
256 /**
257 * Returns all registered notifications
258 *
259 * @return Base[] [description]
260 */
261 public function get_all() {
262 return $this->form_actions;
263 }
264
265 public function get_inserted_post_id( $action_id = 0 ) {
266 $default_post_id = absint( $this->response_data['inserted_post_id'] ?? 0 );
267
268 if ( ! $action_id ) {
269 return $default_post_id;
270 }
271
272 $action_id = absint( $action_id );
273
274 if ( empty( $this->response_data['inserted_posts'] ) ) {
275 return $default_post_id;
276 }
277
278 foreach ( $this->response_data['inserted_posts'] as $posts ) {
279 if ( $action_id === $posts['action_id'] ) {
280 return $posts['post_id'];
281 }
282 }
283
284 return $default_post_id;
285 }
286
287 public function add_response( $values ) {
288 Plugin::instance()->form_handler->add_response_data( $values );
289 }
290
291 public function get_context( $action_slug, $property = '' ) {
292 $context = $this->context[ $action_slug ] ?? array();
293
294 return $property ? $context[ $property ] ?? false : $context;
295 }
296
297 public function add_context( $action_slug, $context ) {
298 $this->context[ $action_slug ] = array_merge( $this->get_context( $action_slug ), $context );
299
300 return $this;
301 }
302
303 public function add_context_once( string $action_slug, array $context ) {
304 $action_context = $this->get_context( $action_slug );
305
306 if ( ! $action_context ) {
307 $this->add_context( $action_slug, $context );
308
309 return $this;
310 }
311
312 foreach ( $context as $name => $value ) {
313 if ( isset( $action_context[ $name ] ) ) {
314 unset( $context[ $name ] );
315 }
316 }
317 $this->add_context( $action_slug, $context );
318
319 return $this;
320 }
321
322 public function in_loop(): bool {
323 return false !== $this->current_position;
324 }
325
326 public function in_loop_or_die() {
327 if ( $this->in_loop() ) {
328 return;
329 }
330
331 wp_die(
332 esc_html( 'The action loop has not been started, see ' . self::class . '::run_actions()' ),
333 __METHOD__,
334 '1.4.0'
335 );
336 }
337
338 public function get_current_action(): Base {
339 $this->in_loop_or_die();
340
341 return $this->get_action( $this->get_position() );
342 }
343
344 public function get_current_condition_manager(): Condition_Manager {
345 $this->in_loop_or_die();
346
347 return $this->get_condition_by_id( $this->get_position() );
348 }
349
350 /**
351 * @param $id
352 *
353 * @return false|Base
354 * @deprecated since 3.0.0
355 * Use \Jet_Form_Builder\Actions\Action_Handler::get_action instead
356 */
357 public function get_action_by_id( $id ) {
358 return $this->get_action( $id );
359 }
360
361 /**
362 * @param $id
363 *
364 * @return false|Condition_Manager
365 */
366 public function get_condition_by_id( $id ) {
367 return $this->form_conditions[ $id ] ?? false;
368 }
369
370 /**
371 * @param $id
372 *
373 * @return false|Events_List
374 */
375 public function get_events_by_id( $id ) {
376 return $this->form_events[ $id ] ?? false;
377 }
378
379 /**
380 * For fix backward compatibility
381 *
382 * @param array $form_events
383 *
384 * @return array
385 */
386 public function merge_events( array $form_events ): array {
387 foreach ( $form_events as $action_id => $event_list ) {
388 $this->form_events[ $action_id ] = $event_list;
389 }
390
391 return $this->form_events;
392 }
393
394 /**
395 * @param $slug
396 *
397 * @return false|Base
398 * @deprecated since 3.0.0
399 * Use \Jet_Form_Builder\Actions\Action_Handler::get_action instead
400 */
401 public function get_action_by_slug( $slug ) {
402 return $this->get_action( $slug );
403 }
404
405 /**
406 * @param int|string $class_slug_or_id
407 *
408 * @return false|Base
409 */
410 public function get_action( $class_slug_or_id ) {
411 $is_number = is_numeric( $class_slug_or_id );
412 $is_class = ! $is_number && class_exists( $class_slug_or_id );
413
414 if ( $is_number ) {
415 return $this->form_actions[ $class_slug_or_id ] ?? false;
416 }
417
418 foreach ( $this->form_actions as $action ) {
419 /** @var Base $action */
420
421 if ( $is_class && is_a( $action, $class_slug_or_id ) ) {
422 return $action;
423 } elseif ( $is_class ) {
424 continue;
425 }
426
427 if ( $action->get_id() !== $class_slug_or_id ) {
428 continue;
429 }
430
431 return $action;
432 }
433
434 return false;
435 }
436
437 public function get_passed_actions(): array {
438 return $this->passed;
439 }
440
441 public function get_skipped_actions(): array {
442 return $this->skipped;
443 }
444
445 public function passing_current() {
446 $this->passing_action( $this->get_position() );
447 }
448
449 public function passing_action( int $action_id ) {
450 $this->passed[] = $action_id;
451
452 return $this;
453 }
454
455 public function skipping_current() {
456 $this->skipping_action( $this->get_position() );
457 }
458
459 public function skipping_action( int $action_id ) {
460 $this->skipped[] = $action_id;
461
462 return $this;
463 }
464
465 /**
466 * @param int|bool $action_id
467 *
468 * @return $this
469 */
470 public function set_current_action( $action_id ) {
471 $this->current_position = $action_id;
472
473 return $this;
474 }
475
476 public function get_position(): int {
477 return (int) $this->current_position;
478 }
479
480 public function start_flow( string $flow_handler ) {
481 $this->current_flow_handler = $flow_handler;
482
483 return $this;
484 }
485
486 public function end_flow() {
487 $this->current_flow_handler = '';
488
489 return $this;
490 }
491
492 /**
493 * @param string $action_class
494 * @param array $props
495 *
496 * @return false|Base
497 * False if action not founded or already added as hidden
498 */
499 public function add_hidden( string $action_class, array $props = array() ) {
500 try {
501 $action = jet_form_builder()->actions->get_action( $action_class );
502 } catch ( Repository_Exception $exception ) {
503 return false;
504 }
505
506 if ( jet_fb_action_handler()->get_action( $action->get_id() ) ) {
507 return false;
508 }
509
510 return $this->add( $action, $props );
511 }
512
513 public function add( Base $action, array $props = array() ): Base {
514 $clone_action = clone $action;
515 $clone_action->_id = $this->get_unique_action_id();
516 $clone_action->toggle_hidden();
517
518 $this->save_action( $clone_action, $props );
519
520 return $clone_action;
521 }
522
523 public function save_action( Base $action, array $props ) {
524 $conditions = $props['conditions'] ?? array();
525 $operator = $props['condition_operator'] ?? 'and';
526 $events = $props['events'] ?? array();
527
528 $condition = new Condition_Manager();
529 $condition->set_conditions( $conditions );
530 $condition->set_condition_operator( $operator );
531
532 $this->form_conditions[ $action->_id ] = $condition;
533 $this->form_actions[ $action->_id ] = $action;
534 $this->form_events[ $action->_id ] = Events_List::create(
535 array_merge( $events, $action->get_required_events() )
536 );
537
538 if ( ! $action->is_hidden() ) {
539 return;
540 }
541
542 $this->reorder_hidden_actions();
543 }
544
545 private function reorder_hidden_actions() {
546 $hidden = array();
547
548 foreach ( $this->form_actions as $action ) {
549 if ( ! $action->is_hidden() ) {
550 continue;
551 }
552 unset( $this->form_actions[ $action->_id ] );
553 $hidden[] = $action;
554 }
555
556 $this->form_actions = $hidden + $this->form_actions;
557 }
558
559 public function get_unique_action_id( int $start_from = 0 ): int {
560 if ( ! array_key_exists( $start_from, $this->form_actions ) ) {
561 return $start_from;
562 }
563
564 return $this->get_unique_action_id( ++$start_from );
565 }
566
567 }
568