PluginProbe
JetFormBuilder — Dynamic Blocks Form Builder / 3.6.5.3
JetFormBuilder — Dynamic Blocks Form Builder v3.6.5.3
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 1.1.2 1.1.3 1.1.4 All 131 releases
jetformbuilder / includes / presets / preset-manager.php

preset-manager.php in JetFormBuilder — Dynamic Blocks Form Builder 3.6.5.3, at includes/presets/preset-manager.php

284 lines 7.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\Presets;
5
6 use Jet_Form_Builder\Classes\Instance_Trait;
7 use Jet_Form_Builder\Classes\Tools;
8 use Jet_Form_Builder\Exceptions\Plain_Default_Exception;
9 use Jet_Form_Builder\Exceptions\Preset_Exception;
10 use Jet_Form_Builder\Presets\Sources;
11 use Jet_Form_Builder\Presets\Types\Base_Preset;
12 use Jet_Form_Builder\Presets\Types\Dynamic_Preset;
13 use Jet_Form_Builder\Presets\Types\General_Preset;
14
15 if ( ! defined( 'WPINC' ) ) {
16 die;
17 }
18
19 /**
20 * @method static Preset_Manager instance()
21 *
22 * Class Preset_Manager
23 * @package Jet_Form_Builder\Presets
24 */
25 class Preset_Manager {
26
27 use Instance_Trait;
28
29 protected $data = null;
30 protected $source = null;
31 protected $defaults = array(
32 'enabled' => false,
33 'from' => 'post',
34 'post_from' => 'current_post',
35 'user_from' => 'current_user',
36 'query_var' => '_post_id',
37 'term_from' => 'current_term',
38 'fields_map' => array(),
39 );
40
41 // phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
42 private $_preset_types = array();
43 private $_source_types;
44
45 // phpcs:enable PSR2.Classes.PropertyDeclaration.Underscore
46
47
48 protected function __construct() {
49 $this->register_preset_types();
50 $this->register_source_types();
51
52 do_action( 'jet-form-builder/after-init/preset-manager' );
53 }
54
55 public function set_form_id( $form_id ): Preset_Manager {
56 if ( ! $form_id ) {
57 return $this;
58 }
59
60 // General_Preset is not unique (Preset_Manager::general() always
61 // returns the same shared instance), and Base_Preset::set_init_data()
62 // merges into any existing $data rather than replacing it. Reset the
63 // instance's $data before loading the current form's preset config,
64 // otherwise a page rendering multiple forms could leak one form's
65 // `restricted` flag (or other preset config) into another form's
66 // permission evaluation via array_merge() carrying over keys the
67 // current form's own config doesn't set - see issues-tracker #20359.
68 //
69 // trust_restriction_flag( true ) is set unconditionally here, not
70 // saved/restored like the equivalent call in get_field_value(): this
71 // form's config is always admin-authored (post meta), so General
72 // Preset's own default already resolves to trusted
73 // (trusts_restriction_flag_by_default()). The explicit call exists
74 // only to document that intent at the call site, not to override a
75 // caller-supplied value - unlike get_field_value(), nothing calls
76 // set_form_id() expecting an untrusted evaluation afterwards.
77 $this->general()
78 ->trust_restriction_flag( true )
79 ->reset_init_data( $this->general()->preset_source( $form_id ) );
80
81 try {
82 $this->general()->get_source();
83 } catch ( Preset_Exception $exception ) {
84 // do nothing
85 }
86
87 return $this;
88 }
89
90 /**
91 * @return Base_Preset[]
92 */
93 protected function preset_types(): array {
94 return $this->_preset_types;
95 }
96
97 /**
98 * @param $slug
99 *
100 * @return Base_Preset|void
101 */
102 public function get_preset_type_raw( $slug ): Base_Preset {
103 if ( isset( $this->_preset_types[ $slug ] ) ) {
104 return $this->_preset_types[ $slug ];
105 }
106
107 _doing_it_wrong(
108 esc_html( static::class . '::' . __METHOD__ ),
109 'Undefined preset type',
110 '1.4.2'
111 );
112 }
113
114 public function get_preset_type( $slug ): Base_Preset {
115 $type = $this->get_preset_type_raw( $slug );
116
117 return $type->is_unique() ? clone $type : $type;
118 }
119
120 /**
121 * @return Dynamic_Preset|Base_Preset
122 */
123 public function dynamic() {
124 return $this->get_preset_type( Dynamic_Preset::SLUG );
125 }
126
127 /**
128 * @return General_Preset|Base_Preset
129 */
130 public function general() {
131 return $this->get_preset_type( General_Preset::SLUG );
132 }
133
134 private function register_source_types() {
135 /** @var Sources\Base_Source[] $types */
136
137 $types = apply_filters(
138 'jet-form-builder/preset/source-types',
139 array(
140 new Sources\Preset_Source_Post(),
141 new Sources\Preset_Source_User(),
142 new Sources\Preset_Source_Query_Var(),
143 new Sources\Preset_Source_Term(),
144 )
145 );
146
147 foreach ( $types as $type ) {
148 $this->register_source_type( $type );
149 }
150 }
151
152 public function register_source_type( Sources\Base_Source $source ) {
153 if ( ! $source->condition() ) {
154 return;
155 }
156 $this->_source_types[ $source->get_id() ] = $source;
157
158 $source->after_register();
159 }
160
161 private function register_preset_types() {
162 $types = array(
163 new Dynamic_Preset(),
164 new General_Preset(),
165 );
166
167 foreach ( $types as $type ) {
168 $this->register_preset_type( $type );
169 }
170 }
171
172 /**
173 * @param $args
174 *
175 * @return Base_Preset
176 * @throws Plain_Default_Exception|Preset_Exception
177 */
178 protected function get_preset_type_manager( $args ) {
179 foreach ( $this->preset_types() as $type ) {
180 $preset = $type->is_unique() ? clone $type : $type;
181
182 if ( $preset->is_active_preset( $args ) ) {
183 return $preset;
184 }
185 }
186
187 throw new Preset_Exception( 'Preset manager is not installed.' );
188 }
189
190
191 protected function register_preset_type( Base_Preset $type ) {
192 $this->_preset_types[ $type->get_slug() ] = $type;
193 }
194
195 /**
196 * Returns field value
197 *
198 * $args here are a form field block's attributes, which live in the
199 * form's own post content/meta and require `edit_post` on the form to
200 * write. That makes this a trusted origin: a `restricted: false` set by
201 * the form author through the editor's "Restrict access" toggle is
202 * honoured, exactly as that toggle's help text promises.
203 *
204 * Untrusted entry points - Rich_Content parsing a submitted field value
205 * via jet_fb_parse_dynamic() - deliberately do NOT declare trust, so a
206 * `restricted` flag smuggled through a submitted value is ignored and the
207 * permission check always runs. Admin-authored call sites use
208 * jet_fb_parse_dynamic_trusted() instead. See issues-tracker #20359.
209 *
210 * @param array $args
211 *
212 * @return [type] [description]
213 */
214 public function get_field_value( $args = array() ) {
215 if ( empty( $args['name'] ) ) {
216 return '';
217 }
218
219 try {
220 $manager = $this->get_preset_type_manager( $args );
221 } catch ( Plain_Default_Exception $exception ) {
222 return $exception->getMessage();
223 } catch ( Preset_Exception $exception ) {
224 return '';
225 }
226
227 /**
228 * Save & restore: get_preset_type_manager() only clones unique preset
229 * types, so for a non-unique one (General_Preset) $manager IS the
230 * process-wide shared instance. Leaving `true` on it would make the
231 * trust sticky for every later caller that reaches the same instance
232 * without an intervening reset - see issues-tracker #20359.
233 */
234 $restore_trust = $manager->trusts_restriction_flag();
235
236 $manager->trust_restriction_flag( true );
237
238 try {
239 return $manager->get_source( $args )->result();
240 } catch ( Preset_Exception $exception ) {
241 return '';
242 } finally {
243 $manager->trust_restriction_flag( $restore_trust );
244 }
245 }
246
247 /**
248 * @param $type
249 *
250 * @return Sources\Base_Source
251 * @throws Preset_Exception
252 */
253 public function get_source_by_type( $type ): Sources\Base_Source {
254 if ( ! isset( $this->_source_types[ $type ] ) ) {
255 throw new Preset_Exception(
256 esc_html( "Undefined source type: {$type}" )
257 );
258 }
259
260 return clone $this->_source_types[ $type ];
261 }
262
263 public function prepare_result( $field_type, $value ) {
264 // Prepare value for date field
265 switch ( $field_type ) {
266 case 'date-field':
267 if ( ! Tools::is_valid_timestamp( $value ) ) {
268 return $value;
269 }
270
271 return date_i18n( 'Y-m-d', $value );
272 case 'datetime-field':
273 if ( ! Tools::is_valid_timestamp( $value ) ) {
274 return $value;
275 }
276
277 return date_i18n( 'Y-m-d\TH:i', $value );
278 default:
279 return apply_filters( 'jet-form-builder/preset/parse-value', $value, $this );
280 }
281 }
282
283 }
284