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