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