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
jetformbuilder / modules / block-parsers / parser-context.php

parser-context.php in JetFormBuilder — Dynamic Blocks Form Builder 3.6.6, at modules/block-parsers/parser-context.php

974 lines 21.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4 namespace Jet_Form_Builder\Request;
5
6 use Jet_Form_Builder\Blocks\Block_Helper;
7 use Jet_Form_Builder\Classes\Arrayable\Array_Tools;
8 use Jet_Form_Builder\Exceptions\Parse_Exception;
9 use Jet_Form_Builder\Exceptions\Repository_Exception;
10 use Jet_Form_Builder\Exceptions\Silence_Exception;
11 use Jet_Form_Builder\Request\Exceptions\Exclude_Field_Exception;
12 use Jet_Form_Builder\Request\Exceptions\Plain_Value_Exception;
13 use JFB_Modules\Block_Parsers\Field_Data_Parser;
14 use JFB_Modules\Block_Parsers\Interfaces\Exclude_Self_Parser;
15 use JFB_Modules\Block_Parsers\Interfaces\Multiple_Parsers;
16 use JFB_Modules\Block_Parsers\Module;
17
18 // If this file is called directly, abort.
19 if ( ! defined( 'WPINC' ) ) {
20 die;
21 }
22
23 /**
24 * Class Parser_Context
25 *
26 * @package Jet_Form_Builder\Request
27 */
28 class Parser_Context {
29
30 protected $name = '';
31
32 /** @var Field_Data_Parser|null */
33 protected $parent_field;
34
35 /** @var string|numeric */
36 protected $index_in_parent = '';
37 private $hide_index = false;
38
39 protected $raw_request = array();
40 protected $raw_files = array();
41
42 private $inside_conditional = false;
43
44 /**
45 * @var bool
46 *
47 * @since 3.0.4
48 */
49 private $guest_allow = false;
50
51 /**
52 * Don't use it outside
53 *
54 * @var Field_Data_Parser[]
55 */
56 public $parsers = array();
57
58 public function apply( $fields = null ) {
59 if ( is_array( $fields ) ) {
60 $this->set_parsers( $fields );
61 }
62
63 /** @var Field_Data_Parser $parser */
64 foreach ( $this->iterate_parsers() as $parser ) {
65 $this->name = $parser->get_name();
66 $parser->update_request();
67 }
68 $this->name = '';
69
70 $this->clear_all();
71 }
72
73 public function set_parsers( $fields ) {
74 foreach ( $this->generate_blocks( $fields ) as $block ) {
75 /** @var Field_Data_Parser $parser */
76 foreach ( $this->generate_parsers( $block ) as $parser ) {
77 if ( ! $parser->get_name() ) {
78 continue;
79 }
80 /**
81 * We have to set this position directly in each object,
82 * because the generation of parsers occurs
83 *
84 * @see https://github.com/Crocoblock/jetformbuilder/issues/339
85 */
86 $parser->set_inside_conditional( $this->is_inside_conditional() );
87
88 $this->parsers[ $parser->get_name() ] = $parser;
89 }
90 }
91 }
92
93 /**
94 * Should used in cases, when no need to check value. Just set
95 */
96 public function apply_request() {
97 /** @var Field_Data_Parser $parser */
98 foreach ( $this->iterate_parsers() as $parser ) {
99 /**
100 * We need to iterate over the value before setting the context
101 * for the case when a large number of records are passed through
102 * a single Field_Data_Parser object. As in the case of exporting
103 *
104 * @see https://github.com/Crocoblock/issues-tracker/issues/3356
105 */
106 $parser->reset();
107
108 try {
109 $parser->set_request();
110
111 } catch ( Exclude_Field_Exception $exception ) {
112 unset( $this->parsers[ $parser->get_name() ] );
113 } catch ( Parse_Exception $exception ) {
114 unset( $this->parsers[ $parser->get_name() ] );
115
116 foreach ( $exception->get_inner() as $key => $value ) {
117 $this->update_request( $value, $key );
118 }
119 }
120 }
121 }
122
123 protected function generate_blocks( $fields ): \Generator {
124 foreach ( $fields as $field ) {
125 try {
126 $this->validate_field( $field );
127
128 yield $field;
129
130 } catch ( Parse_Exception $exception ) {
131 switch ( $exception->getMessage() ) {
132
133 case Module::IS_CONDITIONAL:
134 $prev = $this->is_inside_conditional();
135 $this->set_inside_conditional( true );
136
137 yield from $this->generate_blocks( $exception->get_inner() );
138 $this->set_inside_conditional( $prev );
139 break;
140
141 case Module::NOT_FIELD_HAS_INNER:
142 yield from $this->generate_blocks( $exception->get_inner() );
143 break;
144 }
145 }
146 }
147 }
148
149 /**
150 * @param array $field
151 *
152 * @throws Parse_Exception
153 */
154 public function validate_field( array $field ) {
155 // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped
156 if ( empty( $field['blockName'] ) ) {
157 throw new Parse_Exception( Module::EMPTY_BLOCK_ERROR );
158 }
159
160 if ( empty( $field['innerBlocks'] ) ) {
161 return;
162 }
163
164 if ( strpos( $field['blockName'], 'conditional-block' ) ) {
165 throw new Parse_Exception( Module::IS_CONDITIONAL, $field['innerBlocks'] );
166 }
167 if ( ! Module::instance()->isset_parser( $field['blockName'] ) ) {
168 throw new Parse_Exception( Module::NOT_FIELD_HAS_INNER, $field['innerBlocks'] );
169 }
170 // phpcs:enable WordPress.Security.EscapeOutput.ExceptionNotEscaped
171 }
172
173 /**
174 * @param array $field
175 *
176 * @return false|Field_Data_Parser
177 */
178 protected function generate_parsers( array $field ): \Generator {
179 // reset
180 $this->name = $field['attrs']['name'] ?? '';
181 $this->guest_allow = false;
182
183 $parser = $this->get_parser( $field );
184
185 $parser->set_inner_contexts( $field['innerBlocks'] ?? array() );
186 $parser->set_context( $this );
187
188 if ( ! ( $parser instanceof Exclude_Self_Parser ) ) {
189 yield $parser;
190 }
191
192 if ( ! ( $parser instanceof Multiple_Parsers ) ) {
193 return;
194 }
195
196 yield from $parser->generate_parsers();
197 }
198
199 public function get_file( $name = '' ) {
200 if ( '' === $name ) {
201 $name = $this->name;
202 }
203
204 if ( is_array( $name ) && ! count( $name ) ) {
205 return $this->resolve_files();
206 }
207
208 $path = Array_Tools::path( $name );
209
210 try {
211 $parser = $this->resolve( $path );
212 } catch ( Silence_Exception $exception ) {
213 return $this->raw_files[ $path[0] ] ?? false;
214 }
215
216 return ( $path instanceof Field_Data_Parser ) ? $parser->get_file() : $parser->get_file( array() );
217 }
218
219 public function get_value( $name = '' ) {
220 if ( '' === $name ) {
221 $name = $this->name;
222 }
223
224 if ( is_array( $name ) && ! count( $name ) ) {
225 return $this->resolve_request();
226 }
227
228 $path = Array_Tools::path( $name );
229
230 try {
231 $parser = $this->resolve( $path );
232 } catch ( Plain_Value_Exception $exception ) {
233 return $this->parsers[ $path[0] ];
234 } catch ( Repository_Exception $exception ) {
235 return $this->raw_request[ $path[0] ] ?? '';
236 }
237
238 return ( $path instanceof Field_Data_Parser ) ? $parser->get_value() : $parser->get_value( array() );
239 }
240
241 /**
242 * @param $value
243 * @param string|array $name 'field_name'|'repeater_name'|'repeater_name.0.field_name'|['repeater_name', 0, 'field_name']
244 */
245 public function update_request( $value, $name = '' ) {
246 if ( '' === $name ) {
247 $name = $this->name;
248 }
249
250 if ( is_array( $value ) && is_array( $name ) && ! count( $name ) ) {
251 foreach ( $value as $key => $item ) {
252 $this->update_request( $item, $key );
253 }
254
255 return;
256 }
257
258 $path = Array_Tools::path( $name );
259
260 try {
261 $parser = $this->resolve_parser( $path );
262 } catch ( Silence_Exception $exception ) {
263 $this->parsers[ $path[0] ] = $value;
264
265 return;
266 }
267
268 $parser->set_value( $value );
269 }
270
271 public function update_file( $value, $name = '' ) {
272 if ( '' === $name ) {
273 $name = $this->name;
274 }
275
276 try {
277 $parser = $this->resolve_parser( $name );
278 } catch ( Silence_Exception $exception ) {
279 return;
280 }
281
282 $parser->set_file( $value );
283 }
284
285 public function set_request( array $request ): Parser_Context {
286 $this->raw_request = $request;
287
288 return $this;
289 }
290
291 public function set_files( $files ): Parser_Context {
292 $this->raw_files = $files;
293
294 return $this;
295 }
296
297 /**
298 * @param string $name
299 *
300 * @return array|mixed|string
301 */
302 public function get_request( string $name = '' ) {
303 if ( $name && array_key_exists( $name, $this->raw_request ) ) {
304 return $this->raw_request[ $name ];
305 }
306 $real_request = $this->resolve_request();
307
308 return $name ? ( $real_request[ $name ] ?? '' ) : array_merge(
309 $real_request,
310 $this->raw_request
311 );
312 }
313
314 /**
315 * Allow to replace value of raw_request,
316 * because looks like it can't be replaces in any other way from Parser_Context
317 *
318 * @param string $name Field name to update.
319 * @param mixed $value A new value.
320 * @return void
321 */
322 public function update_request_value( $name, $value ) {
323 $this->raw_request[ $name ] = $value;
324 }
325
326 /**
327 * @param string $name
328 *
329 * @return array|bool
330 */
331 public function get_files( string $name = '' ) {
332 return $name ? ( $this->raw_files[ $name ] ?? false ) : $this->raw_files;
333 }
334
335 /**
336 * @return string
337 */
338 public function get_name(): string {
339 return $this->name;
340 }
341
342 public function is_inside_conditional(): bool {
343 return $this->inside_conditional;
344 }
345
346 public function set_inside_conditional( bool $inside_conditional ): Parser_Context {
347 $this->inside_conditional = $inside_conditional;
348
349 return $this;
350 }
351
352 public function is_secure( $name ): bool {
353 try {
354 $parser = $this->resolve_parser( $name );
355 } catch ( Silence_Exception $exception ) {
356 return false;
357 }
358
359 return $parser->is_secure();
360 }
361
362 /**
363 * @param string|array $name
364 *
365 * @see \JFB_Modules\Form_Record\Controller::generate_request
366 */
367 public function make_secure( $name ) {
368 try {
369 $parser = $this->resolve_parser( $name );
370 } catch ( Silence_Exception $exception ) {
371 return;
372 }
373
374 $parser->make_secure();
375 }
376
377 /**
378 * @param string $attr_name
379 * @param $value
380 * @param string|array $name
381 *
382 * @since 3.0.4
383 */
384 public function update_setting( string $attr_name, $value, $name = '' ) {
385 if ( '' === $name ) {
386 $name = $this->name;
387 }
388
389 try {
390 $parser = $this->resolve_parser( $name );
391 } catch ( Silence_Exception $exception ) {
392 return;
393 }
394
395 $parser->set_setting( $attr_name, $value );
396 }
397
398 /**
399 * @since 3.0.4
400 */
401 public function allow_for_guest() {
402 $this->guest_allow = true;
403 }
404
405 /**
406 * @since 3.0.4
407 */
408 public function is_allowed_for_guest(): bool {
409 return $this->guest_allow;
410 }
411
412 /**
413 * @param array $fields_settings
414 * @param string|array $name
415 *
416 * @since 3.1.0
417 */
418 public function set_field_settings( array $fields_settings, $name = '' ) {
419 if ( '' === $name ) {
420 $name = $this->name;
421 }
422
423 try {
424 $parser = $this->resolve_parser( $name );
425 } catch ( Silence_Exception $exception ) {
426 return;
427 }
428
429 $parser->set_settings( $fields_settings );
430 }
431
432 /**
433 * @param string $field_type
434 * @param string|array $name
435 *
436 * @since 3.1.0
437 */
438 public function set_field_type( string $field_type, $name = '' ) {
439 if ( '' === $name ) {
440 $name = $this->name;
441 }
442
443 $path = Array_Tools::path( $name );
444
445 try {
446 $parser = $this->resolve_parser( $path );
447 } catch ( Silence_Exception $exception ) {
448 if ( 1 === count( $path ) ) {
449 $this->insert_parser( $path[0], $field_type );
450 }
451
452 return;
453 }
454
455 $parser->set_type( $field_type );
456 }
457
458 /**
459 * @param string|array $name
460 *
461 * @return string
462 * @since 3.1.0
463 */
464 public function get_field_type( $name = '' ): string {
465 if ( '' === $name ) {
466 $name = $this->name;
467 }
468
469 try {
470 $parser = $this->resolve_parser( $name );
471 } catch ( Silence_Exception $exception ) {
472 return '';
473 }
474
475 return $parser->get_type();
476 }
477
478 /**
479 * @param string|array $name
480 *
481 * @return string
482 * @since 3.0.4
483 */
484 public function get_class_name( $name = '' ): string {
485 return (string) $this->get_setting( 'class_name', $name );
486 }
487
488 /**
489 * @param string $setting
490 * @param string|array $name
491 *
492 * @return false|mixed
493 */
494 public function get_setting( string $setting, $name = '' ) {
495 if ( '' === $name ) {
496 $name = $this->name;
497 }
498
499 try {
500 $parser = $this->resolve_parser( $name );
501 } catch ( Silence_Exception $exception ) {
502 return false;
503 }
504
505 return $parser->get_setting( $setting );
506 }
507
508 /**
509 * @param string|array $name
510 *
511 * @return array
512 */
513 public function get_settings( $name = '' ): array {
514 if ( '' === $name ) {
515 $name = $this->name;
516 }
517
518 try {
519 $parser = $this->resolve_parser( $name );
520 } catch ( Silence_Exception $exception ) {
521 return array();
522 }
523
524 return $parser->get_settings();
525 }
526
527 public function iterate_fields_types(): \Generator {
528 /**
529 * @var string $name
530 * @var Field_Data_Parser $parser
531 */
532 foreach ( $this->iterate_parsers() as $name => $parser ) {
533 yield $name => $parser->get_type();
534 }
535 }
536
537 public function iterate_fields_settings(): \Generator {
538 /**
539 * @var string $name
540 * @var Field_Data_Parser $parser
541 */
542 foreach ( $this->iterate_parsers() as $name => $parser ) {
543 yield $name => $parser->get_settings();
544 }
545 }
546
547 /**
548 * @return \Generator<Field_Data_Parser>
549 */
550 public function iterate_parsers(): \Generator {
551 foreach ( $this->parsers as $name => $parser ) {
552 if ( $parser instanceof Field_Data_Parser ) {
553 yield $name => $parser;
554 }
555 }
556 }
557
558 public function iterate_settings_list(): \Generator {
559 /**
560 * @var string $name
561 * @var Field_Data_Parser $parser
562 */
563 foreach ( $this->iterate_parsers_list() as $name => $parser ) {
564 yield $name => $parser->get_settings();
565 }
566 }
567
568 public function iterate_types_list(): \Generator {
569 /**
570 * @var string $name
571 * @var Field_Data_Parser $parser
572 */
573 foreach ( $this->iterate_parsers_list() as $name => $parser ) {
574 yield $name => $parser->get_type();
575 }
576 }
577
578 public function iterate_values_table(): \Generator {
579 do {
580 yield $this->iterate_values_row();
581
582 /** @var Field_Data_Parser $parser */
583 foreach ( $this->iterate_parsers_list( false ) as $parser ) {
584 $parser->next_inner();
585 }
586 } while ( ! $this->is_inner_over_parsers() );
587 }
588
589 public function iterate_values_row(): \Generator {
590 /**
591 * @var string $name
592 * @var Field_Data_Parser $parser
593 */
594 foreach ( $this->iterate_parsers() as $parser ) {
595 yield from $parser->iterate_row_value();
596 }
597 }
598
599 public function is_inner_over_parsers(): bool {
600 /** @var Field_Data_Parser $parser */
601 foreach ( $this->iterate_parsers_list( false ) as $parser ) {
602 if ( ! $parser->is_inner_over() ) {
603 return false;
604 }
605 }
606
607 return true;
608 }
609
610 /**
611 * @param bool $break_on_first
612 *
613 * @return \Generator<Field_Data_Parser>
614 */
615 public function iterate_parsers_list( bool $break_on_first = true ): \Generator {
616 /** @var Field_Data_Parser $parser */
617 foreach ( $this->iterate_parsers() as $parser ) {
618 yield from $parser->iterate_self( $break_on_first );
619 }
620 }
621
622 /**
623 * @param string|array $name
624 *
625 * @return \Generator
626 */
627 public function iterate_inner( $name ): \Generator {
628 if ( ! $name ) {
629 return;
630 }
631
632 try {
633 $parser = $this->resolve_parser( $name );
634 } catch ( Silence_Exception $exception ) {
635 return;
636 }
637
638 yield from $parser->iterate_inner();
639 }
640
641 public function clear_all() {
642 foreach ( $this->parsers as $name => $parser ) {
643 unset( $this->raw_request[ $name ] );
644 unset( $this->raw_files[ $name ] );
645 }
646 }
647
648 /**
649 * @param string|array $name
650 *
651 * @return bool
652 */
653 public function has_field( $name ): bool {
654 try {
655 $this->resolve_parser( $name );
656
657 return true;
658 } catch ( Repository_Exception $exception ) {
659 return false;
660 } catch ( Plain_Value_Exception $exception ) {
661 return true;
662 }
663 }
664
665 public function is_collected_error( $name, string $error_name ): bool {
666 try {
667 $parser = $this->resolve_parser( $name );
668 } catch ( Silence_Exception $exception ) {
669 return false;
670 }
671
672 return $parser->is_collected_error( $error_name );
673 }
674
675 public function get_errors( $name ): array {
676 try {
677 $parser = $this->resolve_parser( $name );
678 } catch ( Silence_Exception $exception ) {
679 return array();
680 }
681
682 return $parser->get_errors();
683 }
684
685
686 public function collect_error( $name, $error_name ) {
687 try {
688 $parser = $this->resolve_parser( $name );
689 } catch ( Silence_Exception $exception ) {
690 return;
691 }
692
693 $parser->collect_error( $error_name );
694 }
695
696 public function iterate_errors(): \Generator {
697 /** @var Field_Data_Parser $parser */
698 foreach ( $this->iterate_parsers() as $parser ) {
699 $errors = $parser->get_errors();
700
701 if ( ! $errors ) {
702 continue;
703 }
704
705 yield $parser->get_name() => $errors;
706 }
707 }
708
709 public function iterate_errors_list(): \Generator {
710 /** @var Field_Data_Parser $parser */
711 foreach ( $this->iterate_parsers_list( false ) as $name => $parser ) {
712 $errors = $parser->get_errors();
713
714 if ( ! $errors ) {
715 continue;
716 }
717
718 yield $name => $errors;
719 }
720 }
721
722
723 public function remove( $name ) {
724 $real_path = Array_Tools::path( $name );
725
726 try {
727 $parser = $this->resolve( $name );
728 } catch ( Repository_Exception $exception ) {
729 return;
730 } catch ( Plain_Value_Exception $exception ) {
731 unset( $this->parsers[ $real_path[0] ] );
732
733 return;
734 }
735
736 if ( 1 === count( $real_path ) && ( $parser instanceof Field_Data_Parser ) ) {
737 unset( $this->parsers[ $parser->get_name() ] );
738
739 return;
740 }
741
742 if ( $parser instanceof Field_Data_Parser ) {
743 $parser->get_context()->remove( $parser->get_name() );
744 }
745
746 if ( $parser instanceof Parser_Context ) {
747 $parser->get_parent_field()->remove_context( $parser->get_index_in_parent() );
748 }
749 }
750
751 public function resolve_request( bool $with_inner = true ): array {
752 return iterator_to_array( $this->generate_request( $with_inner ) );
753 }
754
755 public function generate_request( bool $with_inner = true ): \Generator {
756 foreach ( $this->parsers as $name => $parser ) {
757 if ( ! ( $parser instanceof Field_Data_Parser ) ) {
758 yield $name => $parser;
759
760 continue;
761 }
762 $parser->set_with_inner( $with_inner );
763 yield from $parser->iterate_value();
764 $parser->set_with_inner( true );
765 }
766 }
767
768 public function resolve_files(): array {
769 return iterator_to_array( $this->generate_files() );
770 }
771
772 public function generate_files(): \Generator {
773 /** @var Field_Data_Parser $parser */
774 foreach ( $this->iterate_parsers() as $parser ) {
775 yield from $parser->iterate_file();
776 }
777 }
778
779 /**
780 * @param $path
781 *
782 * @return Field_Data_Parser
783 * @throws Plain_Value_Exception|Repository_Exception
784 */
785 public function resolve_parser( $path ): Field_Data_Parser {
786 $item = $this->resolve( $path );
787
788 if ( ! ( $item instanceof Field_Data_Parser ) ) {
789 throw new Repository_Exception();
790 }
791
792 return $item;
793 }
794
795 /**
796 * @param $path
797 *
798 * @return Parser_Context
799 * @throws Plain_Value_Exception|Repository_Exception
800 */
801 public function resolve_context( $path ): Parser_Context {
802 $item = $this->resolve( $path );
803
804 if ( ! ( $item instanceof Parser_Context ) ) {
805 throw new Repository_Exception();
806 }
807
808 return $item;
809 }
810
811 /**
812 * @param $path
813 *
814 * @return Field_Data_Parser|Parser_Context
815 * @throws Plain_Value_Exception
816 * @throws Repository_Exception
817 */
818 public function resolve( $path ) {
819 if ( ! is_array( $path ) ) {
820 $path = Array_Tools::path( $path );
821 }
822
823 if ( ! array_key_exists( $path[0], $this->parsers ) ) {
824 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
825 throw new Repository_Exception( 'undefined_parser', $path );
826 }
827 if ( ! ( $this->parsers[ $path[0] ] instanceof Field_Data_Parser ) ) {
828 throw new Plain_Value_Exception();
829 }
830
831 $name = array_shift( $path );
832
833 return empty( $path ) ? $this->parsers[ $name ] : $this->parsers[ $name ]->resolve( $path );
834 }
835
836 /**
837 * @param $path string[]|string
838 *
839 * @return Parser_Context|Field_Data_Parser
840 * @throws Plain_Value_Exception
841 * @throws Repository_Exception
842 */
843 public function resolve_to_up( $path ) {
844 try {
845 return $this->resolve( $path );
846 } catch ( Silence_Exception $exception ) {
847 return $this->get_parent_field()->get_context()->resolve_to_up( $path );
848 }
849 }
850
851 protected function insert_parser( string $name, string $field_type ): Field_Data_Parser {
852 if ( array_key_exists( $name, $this->parsers ) &&
853 $this->parsers[ $name ] instanceof Field_Data_Parser
854 ) {
855 return $this->parsers[ $name ];
856 }
857
858 $parser = $this->get_parser( array( 'blockName' => $field_type ) );
859 $parser->set_name( $name );
860
861 $value = '';
862 if ( array_key_exists( $name, $this->parsers ) ) {
863 $value = $this->parsers[ $name ];
864 }
865 $this->parsers[ $name ] = $parser;
866 $parser->set_value( $value );
867 $parser->set_context( $this );
868
869 return $parser;
870 }
871
872 /**
873 * @param array $block
874 *
875 * @return Field_Data_Parser
876 */
877 protected function get_parser( array $block ): Field_Data_Parser {
878 $type = Block_Helper::delete_namespace( $block['blockName'] );
879 $parser = Module::instance()->get_parser( $type );
880 $name = $this->name ?: $block['attrs']['name'] ?? '';
881
882 $parser->set_type( $type );
883 $parser->set_name( $name );
884 $parser->set_settings( $block['attrs'] ?? array() );
885
886 return $parser;
887 }
888
889 public function has_request(): bool {
890 return ! empty( $this->parsers );
891 }
892
893 public function get_unique_name( string $computed_field ): string {
894 if (
895 ! $this->has_field( $computed_field ) ||
896 ! jet_fb_action_handler()->in_loop()
897 ) {
898 return $computed_field;
899 }
900
901 $computed_field .= '_' . jet_fb_action_handler()->get_current_action()->_id;
902
903 return $computed_field;
904 }
905
906 public function set_parent( Field_Data_Parser $data_parser ) {
907 $this->parent_field = $data_parser;
908 }
909
910 /**
911 * @return float|int|string
912 */
913 public function get_index_in_parent() {
914 return $this->index_in_parent;
915 }
916
917 /**
918 * @param float|int|string $index_in_parent
919 */
920 public function set_index_in_parent( $index_in_parent ) {
921 $this->index_in_parent = $index_in_parent;
922 }
923
924 /**
925 * @param bool $hide_index
926 */
927 public function set_hide_index( bool $hide_index ) {
928 $this->hide_index = $hide_index;
929 }
930
931 public function get_parent_name(): string {
932 if ( ! $this->get_parent_field() ) {
933 return '';
934 }
935
936 if ( $this->hide_index ) {
937 return $this->get_parent_field()->get_scoped_name();
938 }
939
940 return trim(
941 $this->get_parent_field()->get_scoped_name() . '.' . $this->index_in_parent,
942 '.'
943 );
944 }
945
946 public function get_parent_label(): string {
947 return $this->get_parent_field() ? $this->get_parent_field()->get_scoped_label() : '';
948 }
949
950 /**
951 * @return Field_Data_Parser|null
952 */
953 public function get_parent_field() {
954 return $this->parent_field;
955 }
956
957 public function __clone() {
958 /** @var Field_Data_Parser $parser */
959 foreach ( $this->iterate_parsers() as $name => $parser ) {
960 $this->parsers[ $name ] = clone $parser;
961 $this->parsers[ $name ]->set_context( $this );
962 }
963 }
964
965 public function __debugInfo(): array {
966 $current = clone $this;
967
968 unset( $current->parent_field );
969
970 return get_object_vars( $current );
971 }
972
973 }
974