PluginProbe
JetFormBuilder — Dynamic Blocks Form Builder / 3.6.6
JetFormBuilder — Dynamic Blocks Form Builder v3.6.6
3.6.6.1 3.6.6 3.6.5.4 3.6.5.3 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 All 134 releases
← All changes | includes/actions/action-handler.php +573 -132 1.0.0 → 3.6.6 View file →
@@ -1,132 +1,573 @@
1 -<?php
2 -
3 -namespace Jet_Form_Builder\Actions;
4 -
5 -// If this file is called directly, abort.
6 -use Jet_Form_Builder\Exceptions\Action_Exception;
7 -use Jet_Form_Builder\Plugin;
8 -
9 -if ( ! defined( 'WPINC' ) ) {
10 - die;
11 -}
12 -
13 -/**
14 - * Define Actions handler class class
15 - */
16 -class Action_Handler {
17 -
18 - public $form_id = null;
19 - public $request_data = null;
20 - public $manager = null;
21 -
22 -
23 - public $form_actions = array();
24 - public $is_ajax = false;
25 -
26 - /**
27 - * Data for actions
28 - */
29 - public $size_all;
30 - public $current_position;
31 - public $response_data = array();
32 -
33 -
34 - /**
35 - * Constructor for the class
36 - *
37 - * @param $form_id
38 - * @param array $request_data
39 - */
40 - function __construct( $form_id, $request_data = array() ) {
41 -
42 - $this->form_id = $form_id;
43 - $this->request_data = $request_data;
44 -
45 - $this->set_form_actions();
46 - }
47 -
48 - /**
49 - * Set form actions,
50 - * which were saved in form meta
51 - *
52 - * @return $this
53 - */
54 - public function set_form_actions() {
55 - $available_actions = Plugin::instance()->actions->get_actions();
56 -
57 - $form_actions = Plugin::instance()->post_type->get_actions( $this->form_id );
58 -
59 - foreach ( $form_actions as $form_action ) {
60 - $id = $form_action['type'];
61 -
62 - if ( isset( $available_actions[ $id ] ) ) {
63 - /**
64 - * Save action settings to the class field,
65 - * it allows to not send action settings
66 - * in action hook
67 - */
68 - $available_actions[ $id ]->settings = $form_action['settings'];
69 -
70 - $this->form_actions[ $id ] = $available_actions[ $id ];
71 - }
72 - }
73 -
74 - return $this;
75 - }
76 -
77 -
78 - /**
79 - * Unregister notification by id
80 - *
81 - * @param $id [description]
82 - *
83 - * @return void [description]
84 - */
85 - public function unregister_action( $id ) {
86 -
87 - if ( isset( $this->form_actions[ $id ] ) ) {
88 - unset( $this->form_actions[ $id ] );
89 - }
90 -
91 - }
92 -
93 - /**
94 - * Returns all registered notifications
95 - *
96 - * @return array [description]
97 - */
98 - public function get_all() {
99 - return $this->form_actions;
100 - }
101 -
102 - /**
103 - * Send form notifications
104 - *
105 - * @return array [type] [description]
106 - */
107 - public function do_actions() {
108 -
109 - if ( empty( $this->form_actions ) ) {
110 - throw new Action_Exception( 'failed' );
111 - }
112 -
113 - $this->size_all = sizeof( $this->form_actions );
114 -
115 - do_action( 'jet-form-builder/actions/before-send', $this );
116 -
117 - foreach ( $this->form_actions as $index => $action ) {
118 -
119 - $this->current_position = $index;
120 - /**
121 - * Process single action
122 - */
123 - $action->do_action( $this->request_data, $this );
124 - }
125 -
126 - do_action( 'jet-form-builder/actions/after-send', $this );
127 -
128 - return $this->response_data;
129 - }
130 -
131 -
132 -}
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 +}