PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.0.0.2
JetFormBuilder — Dynamic Blocks Form Builder v3.0.0.2
3.6.5.2 3.6.5.1 3.6.5 3.6.4.2 3.6.4.1 3.6.4 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
action-handler.php
567 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 /**
58 * Hidden actions
59 *
60 * @var array<string, bool>
61 */
62 private $hidden = array();
63
64 public function get_form_id() {
65 return (int) $this->form_id;
66 }
67
68 /**
69 * @param $form_id
70 *
71 * @return Action_Handler
72 */
73 public function set_form_id( $form_id ) {
74 if ( ! $form_id || $form_id === $this->form_id ) {
75 return $this;
76 }
77 $this->form_id = $form_id;
78 $this->set_form_actions();
79
80 return $this;
81 }
82
83 public function add_request( $request ): Action_Handler {
84 if ( ! $this->in_loop() ) {
85 $this->request_data = array_merge( $this->request_data, $request );
86
87 return $this;
88 }
89
90 foreach ( $request as $field_name => $value ) {
91 $field_name = $this->get_unique_field_id( $field_name );
92
93 $this->request_data[ $field_name ] = $value;
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( $this->request_data, $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 ( 0 < (int) $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 } else if ( $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 /**
438 * Use jet_fb_handler()->refer
439 * @return mixed|string
440 * @deprecated 2.1.3
441 *
442 */
443 public function get_refer() {
444 return $this->request_data['__refer'] ?? '';
445 }
446
447 public function get_passed_actions(): array {
448 return $this->passed;
449 }
450
451 public function get_skipped_actions(): array {
452 return $this->skipped;
453 }
454
455 public function passing_current() {
456 $this->passing_action( $this->get_position() );
457 }
458
459 public function passing_action( int $action_id ) {
460 $this->passed[] = $action_id;
461
462 return $this;
463 }
464
465 public function skipping_current() {
466 $this->skipping_action( $this->get_position() );
467 }
468
469 public function skipping_action( int $action_id ) {
470 $this->skipped[] = $action_id;
471
472 return $this;
473 }
474
475 /**
476 * @param int|bool $action_id
477 *
478 * @return $this
479 */
480 public function set_current_action( $action_id ) {
481 $this->current_position = (int) $action_id;
482
483 return $this;
484 }
485
486 public function get_position(): int {
487 return $this->current_position;
488 }
489
490 public function start_flow( string $flow_handler ) {
491 $this->current_flow_handler = $flow_handler;
492
493 return $this;
494 }
495
496 public function end_flow() {
497 $this->current_flow_handler = '';
498
499 return $this;
500 }
501
502 /**
503 * @param string $action_class
504 * @param array $props
505 *
506 * @return false|Base
507 * False if action not founded or already added as hidden
508 */
509 public function add_hidden( string $action_class, array $props = array() ) {
510 try {
511 $action = jet_form_builder()->actions->get_action( $action_class );
512 } catch ( Repository_Exception $exception ) {
513 return false;
514 }
515
516 if ( jet_fb_action_handler()->get_action( $action->get_id() ) ) {
517 return false;
518 }
519
520 $clone_action = clone $action;
521 $clone_action->_id = $this->get_unique_action_id();
522
523 $this->save_action( $clone_action, $props );
524
525 return $clone_action;
526 }
527
528
529 private 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
545 public function get_unique_action_id( int $start_from = 1 ): int {
546 if ( ! array_key_exists( $start_from, $this->form_actions ) ) {
547 return $start_from;
548 }
549
550 return $this->get_unique_action_id( ++ $start_from );
551 }
552
553 public function get_unique_field_id( string $computed_field ): string {
554 if (
555 ! array_key_exists( $computed_field, $this->request_data ) ||
556 ! $this->in_loop()
557 ) {
558 return $computed_field;
559 }
560
561 $computed_field .= '_' . $this->get_current_action()->_id;
562
563 return $computed_field;
564 }
565
566 }
567