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 -215 1.1.0 → 3.6.6 View file →
@@ -1,215 +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\Classes\Tools;
7 -use Jet_Form_Builder\Exceptions\Action_Exception;
8 -use Jet_Form_Builder\Exceptions\Condition_Exception;
9 -use Jet_Form_Builder\Gateways\Gateway_Manager;
10 -use Jet_Form_Builder\Plugin;
11 -
12 -if ( ! defined( 'WPINC' ) ) {
13 - die;
14 -}
15 -
16 -/**
17 - * Define Actions handler class class
18 - */
19 -class Action_Handler {
20 -
21 - public $form_id = null;
22 - public $request_data = null;
23 - public $manager = null;
24 -
25 -
26 - public $form_actions = array();
27 - public $is_ajax = false;
28 -
29 - /**
30 - * Data for actions
31 - */
32 - public $size_all;
33 - public $current_position;
34 - public $response_data = array();
35 -
36 -
37 - /**
38 - * Constructor for the class
39 - *
40 - * @param $form_id
41 - * @param array $request_data
42 - */
43 - public function __construct( $form_id, $request_data = array() ) {
44 - $this->form_id = $form_id;
45 - $this->set_form_actions();
46 - }
47 -
48 - public function add_request( $request ) {
49 - $this->request_data = $request;
50 -
51 - return $this;
52 - }
53 -
54 - /**
55 - * Set form actions,
56 - * which were saved in form meta
57 - *
58 - * @return $this
59 - */
60 - public function set_form_actions() {
61 - $available_actions = Plugin::instance()->actions->get_actions();
62 - $form_actions = Plugin::instance()->post_type->get_actions( $this->form_id );
63 -
64 - foreach ( $form_actions as $form_action ) {
65 - $id = $form_action['id'];
66 - $type = $form_action['type'];
67 - $conditions = isset( $form_action['conditions'] ) ? $form_action['conditions'] : array();
68 -
69 - if ( isset( $available_actions[ $type ] ) ) {
70 - $action = clone $available_actions[ $type ];
71 - /**
72 - * Save action settings to the class field,
73 - * it allows to not send action settings
74 - * in action hook
75 - */
76 - $action->_id = $id;
77 - $action->settings = $form_action['settings'];
78 - $action->conditions = $conditions;
79 -
80 - $this->form_actions[ $id ] = $action;
81 - }
82 - }
83 -
84 - return $this;
85 - }
86 -
87 -
88 - /**
89 - * Unregister notification by id
90 - *
91 - * @param $id [description]
92 - *
93 - * @return void [description]
94 - */
95 - public function unregister_action( $key ) {
96 - if ( is_numeric( $key ) && isset( $this->form_actions[ $key ] ) ) {
97 - unset( $this->form_actions[ $key ] );
98 -
99 - return;
100 - }
101 - foreach ( $this->form_actions as $index => $action ) {
102 - if ( $key === $action->get_id() ) {
103 - unset( $this->form_actions[ $index ] );
104 - }
105 - }
106 - }
107 -
108 - /**
109 - * Returns all registered notifications
110 - *
111 - * @return array [description]
112 - */
113 - public function get_all() {
114 - return $this->form_actions;
115 - }
116 -
117 - /**
118 - * Send form notifications
119 - *
120 - * @return array [type] [description]
121 - * @throws Action_Exception
122 - */
123 - public function do_actions() {
124 -
125 - $this->before_run_actions();
126 - $this->run_actions();
127 - $this->after_run_actions();
128 -
129 - return $this->response_data;
130 - }
131 -
132 - public function before_run_actions() {
133 - $callbacks = array();
134 -
135 - if ( Plugin::instance()->allow_gateways ) {
136 - $callbacks[] = array(
137 - Gateway_Manager::instance(),
138 - Gateway_Manager::BEFORE_ACTIONS_CALLABLE
139 - );
140 - }
141 -
142 - Tools::run_callbacks(
143 - apply_filters( 'jet-form-builder/actions/before-send/callbacks', $callbacks ),
144 - $this
145 - );
146 - }
147 -
148 - public function after_run_actions() {
149 - $callbacks = array();
150 -
151 - if ( Plugin::instance()->allow_gateways ) {
152 - $callbacks[] = array(
153 - Gateway_Manager::instance(),
154 - Gateway_Manager::AFTER_ACTIONS_CALLABLE
155 - );
156 - }
157 -
158 - Tools::run_callbacks(
159 - apply_filters( 'jet-form-builder/actions/after-send/callbacks', $callbacks ),
160 - $this
161 - );
162 -
163 - }
164 -
165 - public function run_actions() {
166 - if ( empty( $this->form_actions ) ) {
167 - throw new Action_Exception( 'failed' );
168 - }
169 -
170 - $this->size_all = sizeof( $this->form_actions );
171 -
172 - foreach ( $this->form_actions as $index => $action ) {
173 -
174 - $this->current_position = $index;
175 -
176 - /**
177 - * Check conditions for action
178 - */
179 - try {
180 - $action->condition( $this );
181 - } catch ( Condition_Exception $exception ) {
182 - continue;
183 - }
184 - /**
185 - * Process single action
186 - */
187 - $action->do_action( $this->request_data, $this );
188 - }
189 -
190 - }
191 -
192 - public function get_inserted_post_id( $action_id = 0 ) {
193 - if ( ! $action_id ) {
194 - return absint( $this->response_data['inserted_post_id'] );
195 - }
196 -
197 - $action_id = absint( $action_id );
198 -
199 - if ( empty( $this->response_data['inserted_posts'] ) ) {
200 - return absint( $this->response_data['inserted_post_id'] );
201 - }
202 -
203 - foreach ( $this->response_data['inserted_posts'] as $posts ) {
204 - if ( $action_id === $posts['action_id'] ) {
205 - return $posts['post_id'];
206 - }
207 - }
208 - }
209 -
210 - public function add_response( $values ) {
211 - Plugin::instance()->form_handler->add_response_data( $values );
212 - }
213 -
214 -
215 -}
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 +}