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 / includes / presets / preset-manager.php

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

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