PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 2.1.4
JetFormBuilder — Dynamic Blocks Form Builder v2.1.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 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / actions / methods / abstract-modifier.php
jetformbuilder / includes / actions / methods Last commit date
exceptions 3 years ago form-record 3 years ago post-modification 3 years ago update-user 3 years ago abstract-modifier.php 3 years ago
abstract-modifier.php
365 lines
1 <?php
2
3 namespace Jet_Form_Builder\Actions\Methods;
4
5 use Jet_Form_Builder\Actions\Methods\Exceptions\Modifier_Exclude_Property;
6 use Jet_Form_Builder\Classes\Tools;
7 use Jet_Form_Builder\Exceptions\Action_Exception;
8 use Jet_Form_Builder\Exceptions\Silence_Exception;
9
10 abstract class Abstract_Modifier {
11
12 public $source_arr = array();
13 protected $current_prop = '';
14 protected $current_value;
15 protected $request = array();
16 protected $excluded_props = array();
17 protected $current_external;
18 protected $external_data = array();
19 protected $fields_map = array();
20
21 protected $action;
22
23 /**
24 * Return object fields
25 *
26 * @return string[] [type] [description]
27 */
28 abstract public function get_object_fields();
29
30 abstract public function get_actions();
31
32 public function get_external_properties() {
33 return array();
34 }
35
36 public function get_required_fields() {
37 return array();
38 }
39
40 /**
41 * @throws Action_Exception
42 */
43 public function run() {
44 $this->attach_items();
45 $this->attach_required_fields();
46 $this->do_action();
47 $this->after_action_externals();
48 }
49
50 public function get_action() {
51 return $this->action;
52 }
53
54 /**
55 * @param string $action
56 *
57 * @return Abstract_Modifier
58 * @throws Silence_Exception
59 */
60 public function set_action( string $action ) {
61 $actions = $this->get_actions();
62
63 if ( isset( $actions[ $action ]['action'] ) && is_callable( $actions[ $action ]['action'] ) ) {
64 $this->action = $action;
65
66 return $this;
67 }
68
69 throw new Silence_Exception(
70 'Undefined action',
71 array(
72 $action,
73 array_keys( $this->get_actions() ),
74 )
75 );
76 }
77
78 /**
79 * @throws Action_Exception
80 */
81 public function do_action() {
82 $action = $this->get_actions()[ $this->get_action() ] ?? array();
83 $action_callback = $action['action'] ?? false;
84 $after_callback = $action['after'] ?? false;
85
86 if ( ! is_callable( $action_callback ) ) {
87 throw new Action_Exception( 'internal_error' );
88 }
89
90 call_user_func( $action_callback, $this );
91
92 if ( ! is_callable( $after_callback ) ) {
93 return;
94 }
95
96 call_user_func( $after_callback, $this );
97 }
98
99 public function attach_items() {
100 $this->fields_map = array_filter( $this->fields_map );
101
102 foreach ( $this->request as $key => $value ) {
103 try {
104 $this->current_prop = $key;
105 $this->current_value = $value;
106
107 $this->attach_item();
108 } catch ( Modifier_Exclude_Property $exception ) {
109 $this->exclude_current_prop();
110
111 } catch ( Silence_Exception $exception ) {
112 continue;
113 }
114 }
115 }
116
117 public function attach_required_fields() {
118 foreach ( $this->get_required_fields() as $name => $options ) {
119 try {
120 $this->current_prop = $name;
121 $this->is_isset_current_prop( $options );
122
123 } catch ( Silence_Exception $exception ) {
124 continue;
125 }
126 }
127 }
128
129 /**
130 * @param array $options
131 *
132 * @throws Silence_Exception
133 */
134 public function is_isset_current_prop( array $options ) {
135 if ( isset( $options['callback'] ) && is_callable( $options['callback'] ) ) {
136 call_user_func( $options['callback'], $options );
137
138 return;
139 }
140 if ( isset( $this->source_arr[ $this->current_prop ] ) ) {
141 throw new Silence_Exception( "{$this->current_prop} is not set." );
142 }
143 }
144
145 /**
146 * @throws Silence_Exception
147 */
148 public function attach_item() {
149 $this->current_prop = $this->get_current_prop_from_fields_map();
150
151 if ( in_array( $this->current_prop, $this->excluded_props, true ) ) {
152 throw new Silence_Exception( "Prop '{$this->current_prop}' is excluded" );
153 }
154
155 $this->before_attach();
156
157 $this->source_arr[ $this->current_prop ] = $this->current_value;
158 }
159
160 /**
161 * @param string $field_name
162 *
163 * @return string
164 * @throws Silence_Exception
165 */
166 public function get_prop_by_field_name( string $field_name ) {
167 /**
168 * At this moment $this->current_prop
169 * store the `field_name`
170 */
171 if ( empty( $this->fields_map[ $field_name ] ) ) {
172 throw new Silence_Exception( 'Field is not used.' );
173 }
174
175 /**
176 * And here we returning the post property
177 * Ex: 'post_content' | 'post_status' | 'jet_tax__slug' | 'custom_meta_key'
178 */
179 return Tools::sanitize_text_field( $this->fields_map[ $field_name ] );
180 }
181
182 public function replace_field_by_prop( string $prop_name, $value ) {
183 $field_name = $this->get_field_name_by_prop( $prop_name );
184
185 if ( false === $field_name ) {
186 $field_name = $this->unique_slug( $prop_name );
187
188 $this->fields_map[ $field_name ] = $prop_name;
189 }
190
191 return $this->set_request(
192 array(
193 $field_name => $value,
194 )
195 );
196 }
197
198 /**
199 * @return string
200 * @throws Silence_Exception
201 */
202 public function get_current_prop_from_fields_map() {
203 return $this->get_prop_by_field_name( $this->current_prop );
204 }
205
206 public function get_value_by_prop( string $prop ) {
207 $field_name = $this->get_field_name_by_prop( $prop );
208
209 return $this->request[ $field_name ] ?? false;
210 }
211
212 public function get_field_name_by_prop( string $search_prop ) {
213 foreach ( $this->fields_map as $field_name => $prop ) {
214 if ( $search_prop === $prop ) {
215 return $field_name;
216 }
217 }
218
219 return false;
220 }
221
222
223 /**
224 * @throws Silence_Exception
225 */
226 public function before_attach() {
227 $property_callback = $this->get_object_fields()[ $this->current_prop ]['before_cb'] ?? false;
228
229 if ( is_callable( $property_callback ) ) {
230 call_user_func( $property_callback, $this );
231
232 return;
233 }
234
235 if ( ! $this->is_reserved_property( $this->current_prop ) ) {
236 call_user_func( array( $this, 'custom_before_attach' ), $this );
237
238 throw new Silence_Exception( 'Property not need to attach' );
239 }
240 }
241
242 /**
243 * @throws Silence_Exception
244 */
245 public function custom_before_attach() {
246 /**
247 * We make the array in reverse order,
248 * in order to check external: meta last,
249 * since it does not have a check ( 'condition_cb' )
250 */
251 $externals = array_reverse( $this->get_external_properties() );
252
253 if ( empty( $externals ) ) {
254 return;
255 }
256
257 foreach ( $externals as $external_key => $external_value ) {
258 $this->current_external = $external_key;
259 $condition_cb = $external_value['condition_cb'] ?? false;
260
261 if ( empty( $condition_cb ) || (
262 is_callable( $condition_cb ) && ! call_user_func( $condition_cb, $this )
263 ) ) {
264 continue;
265 }
266
267 $match_cb = $external_value['match_cb'] ?? false;
268 if ( ! is_callable( $match_cb ) ) {
269 throw new Silence_Exception( "'match_cb' is not callable in {$external_key}" );
270 }
271
272 call_user_func( $match_cb, $this );
273 break;
274 }
275 }
276
277 public function is_reserved_property( $prop ) {
278 $fields = $this->get_object_fields();
279
280 return isset( $fields[ $prop ] ) || in_array( $prop, $fields, true );
281 }
282
283 public function after_action_externals() {
284 $externals = $this->get_external_properties();
285
286 foreach ( $externals as $external_key => $external_value ) {
287 $this->current_external = $external_key;
288 $condition_cb = $external_value['after_action'] ?? false;
289
290 if ( is_callable( $condition_cb ) ) {
291 call_user_func( $condition_cb, $this );
292 }
293 }
294 }
295
296 public function unique_slug( $suffix ) {
297 $form_id = jet_form_builder()->form_handler->form_id ?? 0;
298 $prefix = static::class;
299
300 return "{$prefix}_{$form_id}__{$suffix}";
301 }
302
303 public function set_fields_map( $fields_map ) {
304 $this->fields_map = $fields_map;
305
306 return $this;
307 }
308
309 public function set_external( string $key, array $data ) {
310 if ( ! isset( $this->external_data[ $key ] ) || ! is_array( $this->external_data[ $key ] ) ) {
311 $this->external_data[ $key ] = array();
312 }
313 $this->external_data[ $key ] = array_merge( $this->external_data[ $key ], $data );
314
315 return $this;
316 }
317
318 public function get_external( string $key ) {
319 return $this->external_data[ $key ] ?? array();
320 }
321
322 public function set_current_external( array $data ) {
323 return $this->set_external( $this->current_external, $data );
324 }
325
326 public function get_current_external() {
327 return $this->get_external( (string) $this->current_external );
328 }
329
330 public function set_request( $request ) {
331 $this->request = array_merge( $this->request, $request );
332
333 return $this;
334 }
335
336 public function exclude_current_prop() {
337 $this->exclude_prop( $this->current_prop );
338 }
339
340 /**
341 * @throws Modifier_Exclude_Property
342 */
343 public function exclude_current() {
344 throw new Modifier_Exclude_Property( "Excluding: {$this->current_prop}" );
345 }
346
347 public function exclude_prop( string $prop ) {
348 if ( ! in_array( $prop, $this->excluded_props, true ) ) {
349 $this->excluded_props[] = $prop;
350 }
351
352 unset( $this->source_arr[ $prop ] );
353 }
354
355 /**
356 * @throws Silence_Exception
357 */
358 public function throw_if_empty() {
359 if ( empty( $this->current_value ) ) {
360 throw new Silence_Exception( 'Current field is empty' );
361 }
362 }
363
364 }
365