PluginProbe
Disable Comments & Delete All Comments / trunk
Disable Comments & Delete All Comments vtrunk
1.3.3 1.3.2 trunk 1.0.0 1.0.4 1.0.5 1.0.8 1.0.9 1.1.1 1.1.3 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.3.0 1.3.1
comments-plus / libs / factory / forms / includes / form.class.php

form.class.php in Disable Comments & Delete All Comments trunk, at libs/factory/forms/includes/form.class.php

690 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The file contains a class that represnets an abstraction for forms.
4 *
5 * @author Alex Kovalev <alex.kovalevv@gmail.com>
6 * @copyright (c) 2018, Webcraftic Ltd
7 *
8 * @package factory-forms
9 * @since 1.0.0
10 */
11
12 // Exit if accessed directly
13 if( !defined('ABSPATH') ) {
14 exit;
15 }
16
17 // creating a license manager for each plugin created via the factory
18 add_action('wbcr_factory_forms_480_plugin_created', 'wbcr_factory_forms_480_plugin_created');
19
20 function wbcr_factory_forms_480_plugin_created($plugin)
21 {
22 $plugin->forms = new Wbcr_FactoryForms480_Manager($plugin);
23 }
24
25 if( !class_exists('Wbcr_FactoryForms480_Manager') ) {
26
27 class Wbcr_FactoryForms480_Manager {
28
29 // ----------------------------------------------------
30 // Static fields and methods
31 // ----------------------------------------------------
32
33 /**
34 * This array contains data to use a respective control.
35 *
36 * @since 1.0.0
37 * @var array
38 */
39 public static $registered_controls = array();
40
41 /**
42 * Registers a new control.
43 *
44 * @since 1.0.0
45 * @param mixed[] $item Control data having the following format:
46 * type => a control type
47 * class => a control php class
48 * include => a path to include control code
49 * @return void
50 */
51 public function registerControl($item)
52 {
53 self::$registered_controls[$item['type']] = $item;
54 require_once $item['include'];
55 }
56
57 /**
58 * Registers a set of new controls.
59 *
60 * @see FactoryForms480_Form::registerControl()
61 *
62 * @since 1.0.0
63 * @return void
64 */
65 public function registerControls($data)
66 {
67 foreach($data as $item)
68 $this->registerControl($item);
69 }
70
71 /**
72 * This array contains holder data to use a respective control holder.
73 *
74 * @since 1.0.0
75 * @var array
76 */
77 public static $registered_holders = array();
78
79 /**
80 * Registers a new holder.
81 *
82 * @since 1.0.0
83 * @param mixed[] $item Holder data having the follwoin format:
84 * type => a control holder type
85 * class => a control holder php class
86 * include => a path to include control holder code
87 * @return void
88 */
89 public function registerHolder($item)
90 {
91 self::$registered_holders[$item['type']] = $item;
92 require_once $item['include'];
93 }
94
95 /**
96 * Registers a set of new holder controls.
97 *
98 * @see FactoryForms480_Form::registerHolder()
99 *
100 * @since 1.0.0
101 * @return void
102 */
103 public function registerHolders($data)
104 {
105 foreach($data as $item)
106 $this->registerHolder($item);
107 }
108
109 /**
110 * This array contains custom form element data to use a respective elements.
111 *
112 * @since 1.0.0
113 * @var array
114 */
115 public static $registered_custom_elements = array();
116
117 /**
118 * Registers a new custom form element.
119 *
120 * @since 1.0.0
121 * @return void
122 */
123 public function registerCustomElement($item)
124 {
125 self::$registered_custom_elements[$item['type']] = $item;
126 require_once $item['include'];
127 }
128
129 /**
130 * Registers a set of new custom form elements.
131 *
132 * @see FactoryForms480_Form::registerCustomElement()
133 *
134 * @since 1.0.0
135 * @return void
136 */
137 public function registerCustomElements($data)
138 {
139 foreach($data as $item)
140 $this->registerCustomElement($item);
141 }
142
143 /**
144 * Contains a set of layouts registered for forms.
145 *
146 * @since 1.0.0
147 * @var mixed[]
148 */
149 public static $form_layouts = array();
150
151 /**
152 * Registers a new layout for forms.
153 *
154 * @since 1.0.0
155 * @param array $data A layout data. Has the following format:
156 * name => a name of the layout
157 * class => a layout php class
158 * include => a path to include layout code
159 * @return void
160 */
161 public function registerFormLayout($data)
162 {
163 self::$form_layouts[$data['name']] = $data;
164 }
165
166 /**
167 * Extra propery that determines which UI is used in the admin panel.
168 *
169 * @since 1.0.0
170 * @var string
171 */
172 public static $temper;
173
174 /**
175 * A flat to register control only once.
176 *
177 * @since 3.0.7
178 * @var bool
179 */
180 public static $controls_registered = false;
181 }
182 }
183 if( !class_exists('Wbcr_FactoryForms480_Form') ) {
184 /**
185 * An abstraction for forms.
186 */
187 class Wbcr_FactoryForms480_Form {
188
189 // ----------------------------------------------------
190 // Object fields and methods
191 // ----------------------------------------------------
192
193 /**
194 * A value provider of the form that is used to save and load values.
195 *
196 * @since 1.0.0
197 * @var Wbcr_IFactoryForms480_ValueProvider
198 */
199 private $provider;
200
201 /**
202 * A prefix that will be used for names of input fields in the form.
203 *
204 * @since 1.0.0
205 * @var string
206 */
207 public $scope;
208
209 /**
210 * A form name that is used to call hooks and filter data.
211 *
212 * @since 1.0.0
213 * @var string
214 */
215 public $name = 'default';
216
217 /**
218 * It's not yet input controls. The array contains names of input controls and their
219 * options that are used to render and process input controls.
220 *
221 * @since 1.0.0
222 * @var mixed[]
223 */
224 protected $items = array();
225
226 /**
227 * Full set of input controls available after building the form.
228 *
229 * The array contains objects.
230 *
231 * @since 1.0.0
232 * @var array
233 */
234 private $controls = array();
235
236 /**
237 * A layout for the form.
238 *
239 * @since 1.0.0
240 * @var string
241 */
242 public $form_layout;
243
244 /**
245 * A current form layout used to render a form.
246 *
247 * @since 1.0.0
248 * @var Wbcr_FactoryForms480_FormLayout
249 */
250 public $layout;
251
252 /**
253 * Creates a new instance of a form.
254 *
255 * @since 1.0.0
256 * @param string $options Contains form options to setup.
257 */
258
259 /**
260 * Creates a new instance of a form.
261 *
262 * @since 1.0.0
263 * @param array $options
264 * @param Wbcr_Factory480_Plugin $plugin
265 */
266 public function __construct(array $options, Wbcr_Factory480_Plugin $plugin)
267 {
268 // register controls once, when the first form is created
269 if( !Wbcr_FactoryForms480_Manager::$controls_registered ) {
270
271 do_action('wbcr_factory_forms_480_register_controls', $plugin);
272
273 //if( !empty($plugin) ) {
274 do_action('wbcr_factory_forms_480_register_controls_' . $plugin->getPluginName(), $plugin);
275 //}
276
277 Wbcr_FactoryForms480_Manager::$controls_registered = true;
278 }
279
280 $this->scope = isset($options['scope']) ? $options['scope'] : null;
281 $this->name = isset($options['name']) ? $options['name'] : $this->name;
282 /*$this->all_sites = isset($options['all_sites'])
283 ? $options['all_sites']
284 : false;*/
285
286 if( isset($options['formLayout']) ) {
287 $this->form_layout = $options['formLayout'];
288 } else {
289 $this->form_layout = 'bootstrap-3';
290 }
291
292 Wbcr_FactoryForms480_Manager::$temper = 'flat';
293 }
294
295 /**
296 * Sets a provider for the control.
297 *
298 * @since 1.0.0
299 * @param Wbcr_IFactoryForms480_ValueProvider $provider
300 * @return void
301 */
302 public function setProvider($provider)
303 {
304 $this->provider = $provider;
305 }
306
307 /**
308 * Adds items into the form.
309 *
310 * It's base method to use during configuration form.
311 *
312 * @since 1.0.0
313 * @param array $array An array of items.
314 */
315 public function add($array)
316 {
317 if( (bool)count(array_filter(array_keys($array), 'is_string')) ) {
318 $this->items[] = $array;
319 } else {
320 $this->items = array_merge($this->items, $array);
321 }
322 }
323
324 /**
325 * Returns items to render.
326 *
327 * Has the follwoing hooks:
328 * 'factory_form_items' ( $formName, $items ) to filter form controls before building.
329 *
330 * @since 1.0.0
331 * @return mixed[] Items to render.
332 */
333 public function getItems()
334 {
335 return apply_filters('wbcr_factory_480_form_items', $this->items, $this->name);
336 }
337
338 /**
339 * Returns form controls (control objects).
340 *
341 * @since 1.0.0
342 * @return Wbcr_FactoryForms480_Control[]
343 */
344 public function getControls()
345 {
346 if( !empty($this->controls) ) {
347 return $this->controls;
348 }
349 $this->createControls();
350
351 return $this->controls;
352 }
353
354 /**
355 * Builds a form items to the control objects ready to use.
356 *
357 * @param null $holder
358 * @return Wbcr_FactoryForms480_Control[]
359 */
360
361 public function createControls($holder = null)
362 {
363 $items = ($holder == null) ? $this->getItems() : $holder['items'];
364
365 foreach($items as $item) {
366
367 if( $this->isControlHolder($item) && $this->isControl($item) ) {
368
369 $this->controls[] = $this->createControl($item);
370 $this->createControls($item);
371 // if a current item is a control holder
372 } elseif( $this->isControlHolder($item) ) {
373
374 $this->createControls($item);
375 // if a current item is an input control
376 } elseif( $this->isControl($item) ) {
377
378 $this->controls[] = $this->createControl($item);
379 // if a current item is an input control
380 } elseif( $this->isCustomElement($item) ) {
381
382 // nothing
383
384 // otherwise, show the error
385 } else {
386 die('[ERROR] Invalid item.');
387 }
388 }
389
390 return $this->controls;
391 }
392
393 /**
394 * Create an element.
395 *
396 * @since 1.0.0
397 * @param array $item Item data.
398 * @return Wbcr_FactoryForms480_FormElement|null A form element.
399 */
400 public function createElement($item)
401 {
402
403 if( $this->isControl($item) ) {
404 return $this->createControl($item);
405 } elseif( $this->isControlHolder($item) ) {
406 return $this->createHolder($item);
407 } elseif( $this->isCustomElement($item) ) {
408 return $this->createCustomElement($item);
409 } else {
410 printf('[ERROR] The element with the type <strong>%s</strong> was not found.', $item['type']);
411 exit;
412 }
413 }
414
415 /**
416 * Creates a set of elements.
417 *
418 * @since 1.0.0
419 * @param mixed[] $item Data of items.
420 * @return Wbcr_FactoryForms480_FormElement[] Created elements.
421 */
422 public function createElements($items = array())
423 {
424 $objects = array();
425 foreach($items as $item)
426 $objects[] = $this->createElement($item);
427
428 return $objects;
429 }
430
431 /**
432 * Create a control.
433 *
434 * @since 1.0.0
435 * @param array $item Item data.
436 * @return Wbcr_FactoryForms480_Control A control object.
437 */
438 public function createControl($item)
439 {
440 $object = null;
441
442 if( is_array($item) ) {
443
444 $control_data = Wbcr_FactoryForms480_Manager::$registered_controls[$item['type']];
445
446 require_once($control_data['include']);
447
448 $options = $item;
449 $options['scope'] = $this->scope;
450
451 $object = new $control_data['class']($options, $this);
452 } elseif( gettype($item) == 'object' ) {
453 $object = $item;
454 } else {
455 die('[ERROR] Invalid input control.');
456 }
457
458 $object->setProvider($this->provider);
459
460 return $object;
461 }
462
463 /**
464 * Create a control holder.
465 *
466 * @since 1.0.0
467 * @param array $item Item data.
468 * @return Wbcr_FactoryForms480_Holder A control holder object.
469 */
470 public function createHolder($item)
471 {
472 $object = null;
473
474 if( is_array($item) ) {
475
476 $holderData = Wbcr_FactoryForms480_Manager::$registered_holders[$item['type']];
477 require_once($holderData['include']);
478
479 $object = new $holderData['class']($item, $this);
480 } elseif( gettype($item) == 'object' ) {
481 $object = $item;
482 } else {
483 die('[ERROR] Invalid control holder.');
484 }
485
486 return $object;
487 }
488
489 /**
490 * Create a custom form element.
491 *
492 * @since 1.0.0
493 * @param mixed $item Item data.
494 * @return Wbcr_FactoryForms480_FormElement A custom form element object.
495 */
496 public function createCustomElement($item)
497 {
498 $object = null;
499
500 if( is_array($item) ) {
501
502 $data = Wbcr_FactoryForms480_Manager::$registered_custom_elements[$item['type']];
503 require_once($data['include']);
504
505 $options = $item;
506 $object = new $data['class']($options, $this);
507 } elseif( gettype($item) == 'object' ) {
508 $object = $item;
509 } else {
510 die('[ERROR] Invalid custom form element.');
511 }
512
513 return $object;
514 }
515
516 /**
517 * Renders a form.
518 *
519 * @since 1.0.0
520 * @param mixed[] $options Options for a form layout.
521 * @return void
522 */
523 public function html($options = array())
524 {
525
526 if( !isset(Wbcr_FactoryForms480_Manager::$form_layouts[$this->form_layout]) ) {
527 die(sprintf('[ERROR] The form layout %s was not found.', $this->form_layout));
528 }
529
530 // include a render code
531 $layout_data = Wbcr_FactoryForms480_Manager::$form_layouts[$this->form_layout];
532 require_once($layout_data['include']);
533
534 $this->connectAssets();
535
536 if( $this->provider ) {
537 $this->provider->init();
538 }
539 $layout = new $layout_data['class']($options, $this);
540 $this->layout = $layout;
541 $this->layout->render();
542 }
543
544 /**
545 * Connects assets (css and js).
546 *
547 * @since 1.0.0
548 * @param mixed[] $options Options for a form layout.
549 * @return void
550 */
551 private function connectAssets()
552 {
553
554 $this->connectAssetsForItems();
555 $layout_data = Wbcr_FactoryForms480_Manager::$form_layouts[$this->form_layout];
556
557 if( $layout_data['name'] == 'default' ) {
558 if( isset($layout_data['style']) ) {
559 wp_enqueue_style('wbcr-factory-form-000-default-layout', $layout_data['style']);
560 }
561 if( isset($layout_data['script']) ) {
562 wp_enqueue_script('wbcr-factory-form-000-default-layout-', $layout_data['script']);
563 }
564 } else {
565 if( isset($layout_data['style']) ) {
566 wp_enqueue_style('wbcr-factory-form-layout-' . $layout_data['name'], $layout_data['style']);
567 }
568 if( isset($layout_data['script']) ) {
569 wp_enqueue_script('wbcr-factory-form-layout-' . $layout_data['name'], $layout_data['script']);
570 }
571 }
572 }
573
574
575 /**
576 * Connects scripts and styles of form items.
577 *
578 * @since 1.0.0
579 * @param mixed[] $items Items for which it's nessesary to connect scripts and styles.
580 * @return void
581 */
582 public static function connectAssetsForItems($items = array())
583 {
584 foreach($items as $item)
585 self::connectAssetsForItem($item);
586 }
587
588 /**
589 * Connects scripts and styles of form item.
590 *
591 * @since 1.0.0
592 * @param mixed[] $item Item for which it's nessesary to connect scripts and styles.
593 * @return void
594 */
595 public static function connectAssetsForItem($item)
596 {
597 if( !is_array($item) ) {
598 return;
599 }
600
601 $type = $item['type'];
602
603 $haystack = array();
604 if( self::isControl($type) ) {
605 $haystack = Wbcr_FactoryForms480_Manager::$registered_controls;
606 } elseif( self::isControlHolder($type) ) {
607 $haystack = Wbcr_FactoryForms480_Manager::$registered_holders;
608 }
609
610 if( isset($haystack[$type]) ) {
611 if( isset($haystack[$type]['style']) ) {
612 $style = $haystack[$type]['style'];
613 if( !wp_style_is($style) ) {
614 wp_enqueue_style('factory-form-control-' . $type, $style);
615 }
616 }
617 if( isset($haystack[$type]['script']) ) {
618 $script = $haystack[$type]['script'];
619 if( !wp_script_is($script) ) {
620 wp_enqueue_script('factory-form-control-' . $type, $script, array('jquery'));
621 }
622 }
623 }
624
625 if( isset($item['items']) ) {
626 self::connectAssetsForItem($item['items']);
627 }
628 }
629
630 /**
631 * Saves form data by using a specified value provider.
632 *
633 * @since 1.0.0
634 */
635 public function save()
636 {
637 if( !$this->provider ) {
638 return null;
639 }
640
641 $controls = $this->getControls();
642
643 foreach($controls as $control) {
644 $values = $control->getValuesToSave();
645
646 foreach($values as $key_to_save => $value_to_save) {
647 $this->provider->setValue($key_to_save, $value_to_save);
648 }
649 }
650
651 $this->provider->saveChanges();
652 }
653
654 /**
655 * Returns true if a given item is an input control item.
656 *
657 * @since 1.0.0
658 * @param mixed[] $item
659 * @return bool
660 */
661 public static function isControl($item)
662 {
663 return isset(Wbcr_FactoryForms480_Manager::$registered_controls[$item['type']]);
664 }
665
666 /**
667 * Returns true if a given item is an control holder item.
668 *
669 * @since 1.0.0
670 * @param mixed[] $item
671 * @return bool
672 */
673 public static function isControlHolder($item)
674 {
675 return isset(Wbcr_FactoryForms480_Manager::$registered_holders[$item['type']]);
676 }
677
678 /**
679 * Returns true if a given item is html markup.
680 *
681 * @since 1.0.0
682 * @param mixed[] $item
683 * @return bool
684 */
685 public static function isCustomElement($item)
686 {
687 return isset(Wbcr_FactoryForms480_Manager::$registered_custom_elements[$item['type']]);
688 }
689 }
690 }