PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.2.3
JetFormBuilder — Dynamic Blocks Form Builder v3.2.3
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
573 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 * @since 3.2.0
218 */
219 do_action( "jet-form-builder/before-do-action/{$action->get_id()}", $action );
220
221 /**
222 * Process single action
223 */
224 $action->do_action( jet_fb_context()->resolve_request(), $this );
225
226 /**
227 * We save the ID of the current action,
228 * for possible logging of form entries
229 */
230 $this->passing_current();
231 }
232
233 /**
234 * Unregister notification by id
235 *
236 * @param $key
237 *
238 * @return Action_Handler [description]
239 */
240 public function unregister_action( $key ) {
241 if ( is_numeric( $key ) && isset( $this->form_actions[ $key ] ) ) {
242 unset( $this->form_actions[ $key ] );
243 unset( $this->form_conditions[ $key ] );
244 unset( $this->form_events[ $key ] );
245
246 return $this;
247 }
248 foreach ( $this->form_actions as $index => $action ) {
249 if ( $key === $action->get_id() ) {
250 unset( $this->form_actions[ $index ] );
251 unset( $this->form_conditions[ $index ] );
252 unset( $this->form_events[ $index ] );
253
254 return $this;
255 }
256 }
257
258 return $this;
259 }
260
261 /**
262 * Returns all registered notifications
263 *
264 * @return Base[] [description]
265 */
266 public function get_all() {
267 return $this->form_actions;
268 }
269
270 public function get_inserted_post_id( $action_id = 0 ) {
271 $default_post_id = absint( $this->response_data['inserted_post_id'] ?? 0 );
272
273 if ( ! $action_id ) {
274 return $default_post_id;
275 }
276
277 $action_id = absint( $action_id );
278
279 if ( empty( $this->response_data['inserted_posts'] ) ) {
280 return $default_post_id;
281 }
282
283 foreach ( $this->response_data['inserted_posts'] as $posts ) {
284 if ( $action_id === $posts['action_id'] ) {
285 return $posts['post_id'];
286 }
287 }
288
289 return $default_post_id;
290 }
291
292 public function add_response( $values ) {
293 Plugin::instance()->form_handler->add_response_data( $values );
294 }
295
296 public function get_context( $action_slug, $property = '' ) {
297 $context = $this->context[ $action_slug ] ?? array();
298
299 return $property ? $context[ $property ] ?? false : $context;
300 }
301
302 public function add_context( $action_slug, $context ) {
303 $this->context[ $action_slug ] = array_merge( $this->get_context( $action_slug ), $context );
304
305 return $this;
306 }
307
308 public function add_context_once( string $action_slug, array $context ) {
309 $action_context = $this->get_context( $action_slug );
310
311 if ( ! $action_context ) {
312 $this->add_context( $action_slug, $context );
313
314 return $this;
315 }
316
317 foreach ( $context as $name => $value ) {
318 if ( isset( $action_context[ $name ] ) ) {
319 unset( $context[ $name ] );
320 }
321 }
322 $this->add_context( $action_slug, $context );
323
324 return $this;
325 }
326
327 public function in_loop(): bool {
328 return false !== $this->current_position;
329 }
330
331 public function in_loop_or_die() {
332 if ( $this->in_loop() ) {
333 return;
334 }
335
336 wp_die(
337 esc_html( 'The action loop has not been started, see ' . self::class . '::run_actions()' ),
338 __METHOD__,
339 '1.4.0'
340 );
341 }
342
343 public function get_current_action(): Base {
344 $this->in_loop_or_die();
345
346 return $this->get_action( $this->get_position() );
347 }
348
349 public function get_current_condition_manager(): Condition_Manager {
350 $this->in_loop_or_die();
351
352 return $this->get_condition_by_id( $this->get_position() );
353 }
354
355 /**
356 * @param $id
357 *
358 * @return false|Base
359 * @deprecated since 3.0.0
360 * Use \Jet_Form_Builder\Actions\Action_Handler::get_action instead
361 */
362 public function get_action_by_id( $id ) {
363 return $this->get_action( $id );
364 }
365
366 /**
367 * @param $id
368 *
369 * @return false|Condition_Manager
370 */
371 public function get_condition_by_id( $id ) {
372 return $this->form_conditions[ $id ] ?? false;
373 }
374
375 /**
376 * @param $id
377 *
378 * @return false|Events_List
379 */
380 public function get_events_by_id( $id ) {
381 return $this->form_events[ $id ] ?? false;
382 }
383
384 /**
385 * For fix backward compatibility
386 *
387 * @param array $form_events
388 *
389 * @return array
390 */
391 public function merge_events( array $form_events ): array {
392 foreach ( $form_events as $action_id => $event_list ) {
393 $this->form_events[ $action_id ] = $event_list;
394 }
395
396 return $this->form_events;
397 }
398
399 /**
400 * @param $slug
401 *
402 * @return false|Base
403 * @deprecated since 3.0.0
404 * Use \Jet_Form_Builder\Actions\Action_Handler::get_action instead
405 */
406 public function get_action_by_slug( $slug ) {
407 return $this->get_action( $slug );
408 }
409
410 /**
411 * @param int|string $class_slug_or_id
412 *
413 * @return false|Base
414 */
415 public function get_action( $class_slug_or_id ) {
416 $is_number = is_numeric( $class_slug_or_id );
417 $is_class = ! $is_number && class_exists( $class_slug_or_id );
418
419 if ( $is_number ) {
420 return $this->form_actions[ $class_slug_or_id ] ?? false;
421 }
422
423 foreach ( $this->form_actions as $action ) {
424 /** @var Base $action */
425
426 if ( $is_class && is_a( $action, $class_slug_or_id ) ) {
427 return $action;
428 } elseif ( $is_class ) {
429 continue;
430 }
431
432 if ( $action->get_id() !== $class_slug_or_id ) {
433 continue;
434 }
435
436 return $action;
437 }
438
439 return false;
440 }
441
442 public function get_passed_actions(): array {
443 return $this->passed;
444 }
445
446 public function get_skipped_actions(): array {
447 return $this->skipped;
448 }
449
450 public function passing_current() {
451 $this->passing_action( $this->get_position() );
452 }
453
454 public function passing_action( int $action_id ) {
455 $this->passed[] = $action_id;
456
457 return $this;
458 }
459
460 public function skipping_current() {
461 $this->skipping_action( $this->get_position() );
462 }
463
464 public function skipping_action( int $action_id ) {
465 $this->skipped[] = $action_id;
466
467 return $this;
468 }
469
470 /**
471 * @param int|bool $action_id
472 *
473 * @return $this
474 */
475 public function set_current_action( $action_id ) {
476 $this->current_position = $action_id;
477
478 return $this;
479 }
480
481 public function get_position(): int {
482 return (int) $this->current_position;
483 }
484
485 public function start_flow( string $flow_handler ) {
486 $this->current_flow_handler = $flow_handler;
487
488 return $this;
489 }
490
491 public function end_flow() {
492 $this->current_flow_handler = '';
493
494 return $this;
495 }
496
497 /**
498 * @param string $action_class
499 * @param array $props
500 *
501 * @return false|Base
502 * False if action not founded or already added as hidden
503 */
504 public function add_hidden( string $action_class, array $props = array() ) {
505 try {
506 $action = jet_form_builder()->actions->get_action( $action_class );
507 } catch ( Repository_Exception $exception ) {
508 return false;
509 }
510
511 if ( jet_fb_action_handler()->get_action( $action->get_id() ) ) {
512 return false;
513 }
514
515 return $this->add( $action, $props );
516 }
517
518 public function add( Base $action, array $props = array() ): Base {
519 $clone_action = clone $action;
520 $clone_action->_id = $this->get_unique_action_id();
521 $clone_action->toggle_hidden();
522
523 $this->save_action( $clone_action, $props );
524
525 return $clone_action;
526 }
527
528 public function save_action( Base $action, array $props ) {
529 $conditions = $props['conditions'] ?? array();
530 $operator = $props['condition_operator'] ?? 'and';
531 $events = $props['events'] ?? array();
532
533 $condition = new Condition_Manager();
534 $condition->set_conditions( $conditions );
535 $condition->set_condition_operator( $operator );
536
537 $this->form_conditions[ $action->_id ] = $condition;
538 $this->form_actions[ $action->_id ] = $action;
539 $this->form_events[ $action->_id ] = Events_List::create(
540 array_merge( $events, $action->get_required_events() )
541 );
542
543 if ( ! $action->is_hidden() ) {
544 return;
545 }
546
547 $this->reorder_hidden_actions();
548 }
549
550 private function reorder_hidden_actions() {
551 $hidden = array();
552
553 foreach ( $this->form_actions as $action ) {
554 if ( ! $action->is_hidden() ) {
555 continue;
556 }
557 unset( $this->form_actions[ $action->_id ] );
558 $hidden[] = $action;
559 }
560
561 $this->form_actions = $hidden + $this->form_actions;
562 }
563
564 public function get_unique_action_id( int $start_from = 0 ): int {
565 if ( ! array_key_exists( $start_from, $this->form_actions ) ) {
566 return $start_from;
567 }
568
569 return $this->get_unique_action_id( ++$start_from );
570 }
571
572 }
573