1: <?php
2: 3: 4:
5: class Sidecar_Form {
6: 7: 8:
9: var $plugin;
10:
11: 12: 13:
14: var $admin_page;
15:
16: 17: 18:
19: var $form_name;
20:
21: 22: 23:
24: var $form_label;
25:
26: 27: 28:
29: var $requires_api;
30:
31: 32: 33:
34: private $_settings;
35:
36: 37: 38:
39: private $_default_settings_values;
40:
41: 42: 43:
44: private $_fields = array();
45:
46: 47: 48:
49: private $_sections = array();
50:
51: 52: 53:
54: private $_buttons = array();
55:
56: 57: 58:
59: private $_initialized = false;
60:
61: 62: 63:
64: private $_required_field_names;
65:
66: 67: 68: 69:
70: function __construct( $form_name, $args = array() ) {
71: $this->form_name = $form_name;
72: 73: 74:
75: foreach( $args as $property => $value ) {
76: if ( property_exists( $this, $property ) ) {
77: $this->$property = $value;
78: } else if ( property_exists( $this, $property = "form_{$property}" ) ) {
79: $this->$property = $value;
80: }
81: }
82:
83: }
84:
85: 86: 87:
88: function get_sections() {
89: return $this->_sections;
90: }
91:
92: 93: 94:
95: function get_fields() {
96: return $this->_fields;
97: }
98:
99: 100: 101: 102:
103: function get_field( $field_name ) {
104: return isset( $this->_fields[$field_name] ) ? $this->_fields[$field_name] : false;
105: }
106:
107: 108: 109: 110:
111: function has_field( $field_name ) {
112: return isset( $this->_fields[$field_name] );
113: }
114:
115: 116: 117:
118: function has_fields() {
119: return 0 < count( $this->_fields ) ;
120: }
121:
122: 123: 124: 125:
126: function get_section( $section_name ) {
127: return isset( $this->_sections[$section_name] ) ? $this->_sections[$section_name] : false;
128: }
129:
130: 131: 132: 133:
134: function has_section( $section_name ) {
135: return isset( $this->_sections[$section_name] );
136: }
137:
138: 139: 140:
141: function has_sections() {
142: return 0 < count( $this->_sections ) ;
143: }
144:
145: 146: 147: 148:
149: function get_field_names( $section_name ) {
150: return array_keys( $this->_sections[$section_name]->fields );
151: }
152:
153: 154: 155: 156: 157:
158: function has_section_fields( $section_name = false ) {
159: $has_fields = false;
160: if ( $section_name && $this->has_section( $section_name ) ) {
161: $has_fields = 0 < count( $this->_sections[$section_name]->fields );
162: }
163: return $has_fields;
164: }
165:
166: 167: 168: 169: 170:
171: function get_section_fields( $section_name = false ) {
172: $fields = array();
173: if ( $section_name && $this->has_section( $section_name ) ) {
174: $fields = $this->_sections[$section_name]->fields;
175: }
176: return $fields;
177: }
178:
179: 180: 181:
182: function the_form() {
183: echo $this->get_html();
184: return $this;
185: }
186:
187: 188: 189:
190: function get_html() {
191: ob_start();
192: 193: 194:
195: settings_fields( $settings_group = $this->plugin->option_name );
196:
197: 198: 199: 200:
201: global $wp_settings_fields;
202: $save_wp_settings_fields = $wp_settings_fields;
203: $hidden_fields = array();
204: $fields = $this->get_fields();
205: if ( isset( $wp_settings_fields[$this->plugin->option_name] ) ) {
206: foreach( $wp_settings_fields[$this->plugin->option_name] as $section_name => $section ) {
207: foreach( $section as $field_name => $field ) {
208: $unset = false;
209: if ( ! isset( $fields[$field_name] ) ) {
210: $unset = true;
211: } else if ( 'hidden' == $field['args']['field']->field_type ) {
212: $hidden_fields[] = $field['args']['field'];
213: $unset = true;
214: }
215: if ( $unset ) {
216: unset( $wp_settings_fields[$this->plugin->option_name][$section_name][$field_name] );
217: } else {
218: 219: 220:
221: $field_object = $field['args']['field'];
222: $wp_settings_fields[$this->plugin->option_name][$section_name][$field_name]['args']['label_for'] = $field_object->get_wrapper_id();
223: }
224: }
225: }
226: }
227: 228: 229: 230:
231: $hidden_fields_html = array();
232: foreach( $hidden_fields as $hidden_field ) {
233: $hidden_fields_html[] = $hidden_field->get_html();
234: }
235: $hidden_fields_html = implode( "\n", $hidden_fields_html );
236:
237: 238: 239:
240: do_settings_sections( $this->plugin->option_name );
241:
242: $form_fields_html = ob_get_clean();
243:
244: $options_url = admin_url( 'options.php' );
245:
246: if ( ! $this->admin_page->has_tabs() ) {
247: $hidden_section_input_html = '';
248: } else {
249: $tab_slug = $this->admin_page->get_current_tab()->tab_slug;
250:
251: $hidden_section_input_html = <<<HTML
252: <input type="hidden" name="{$this->plugin->option_name}[_sidecar_form_meta][plugin]" value="{$this->plugin->plugin_name}" />
253: <input type="hidden" name="{$this->plugin->option_name}[_sidecar_form_meta][page]" value="{$this->admin_page->page_name}" />
254: <input type="hidden" name="{$this->plugin->option_name}[_sidecar_form_meta][tab]" value="{$tab_slug}" />
255: <input type="hidden" name="{$this->plugin->option_name}[_sidecar_form_meta][form]" value="{$this->form_name}" />
256: HTML;
257: }
258: $buttons_html = array();
259: foreach( $this->_buttons as $button ) {
260: $button_html = get_submit_button(
261: $button->button_text,
262: $button->button_type,
263: $button->input_name,
264: $button->button_wrap,
265: $button->other_attributes
266: );
267: $buttons_html[] = preg_replace( '#^<p(.*)</p>#', '<span$1</span>', $button_html );
268: }
269: $buttons_html = implode( "\n", $buttons_html );
270: $form = <<<HTML
271: <form action="{$options_url}" method="POST">
272: {$hidden_section_input_html}
273: <div class="form-fields">
274: {$hidden_fields_html}
275: {$form_fields_html}
276: </div>
277: <div class="form-buttons">
278: {$buttons_html}
279: </div>
280: </form>
281: HTML;
282: $wp_settings_fields = $save_wp_settings_fields;
283: return $form;
284: }
285:
286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300:
301: function add_button( $button_name, $button_text, $args = array() ) {
302: $args['button_name'] = $button_name;
303: $args['button_text'] = $button_text;
304:
305: $this->_buttons[$button_name] = (object)$args;
306: }
307:
308: 309: 310: 311: 312:
313: function get_button( $button_name ) {
314: return isset( $this->_buttons[$button_name] ) ? $this->_buttons[$button_name] : false;
315: }
316:
317: 318:
319: function initialize() {
320: if ( ! $this->_initialized ) {
321:
322: if ( ! $this->has_fields() ) {
323: $this->plugin->initialize_form( $this );
324: }
325: $this->_initialized = true;
326:
327: }
328: }
329:
330: 331: 332:
333: function initialize_sections( $plugin ) {
334: $settings = $this->get_settings();
335: foreach( $this->get_sections() as $section_name => $section ) {
336: if ( ! $section->section_handler )
337: $section->section_handler = array( $plugin, 'the_form_section' );
338: add_settings_section( $section_name, $section->section_title, $section->section_handler, $this->plugin->option_name, array(
339: 'section' => $section,
340: 'form' => $this,
341: 'plugin' => $plugin,
342: 'settings' => $settings,
343: ));
344: foreach( $section->fields as $field_name => $field ) {
345: if ( ! $field->field_handler )
346: $field->field_handler = array( $this, '_the_form_field_callback' );
347: $field_label = 'checkbox' != $field->field_type ? $field->field_label : false;
348: add_settings_field( $field_name, $field_label, $field->field_handler, $this->plugin->option_name, $section_name, array(
349: 'field' => $field,
350: 'section' => $section,
351: 'form' => $this,
352: 'plugin' => $plugin,
353: 'settings' => $settings,
354: ));
355: }
356: }
357: }
358:
359: 360: 361:
362: function _the_form_field_callback( $args ) {
363: $this->plugin->the_form_field( $args['field']->field_name, $args['form']->form_name );
364: }
365:
366: 367: 368:
369: function initialize_buttons( $plugin ) {
370: foreach( $this->_buttons as $button_name => $button ) {
371:
372: if ( ! isset( $button->button_type ) )
373: $button->button_type = 'primary';
374:
375: if ( ! isset( $button->input_name ) )
376: if ( 'primary' == $button->button_type ) {
377: $button->input_name = 'submit';
378: } else {
379: $button->input_name = "{$this->plugin->option_name}[action][{$button_name}]";
380: }
381:
382: if ( ! isset( $button->button_wrap ) )
383: $button->button_wrap = true;
384:
385: if ( ! isset( $button->other_attributes ) )
386: $button->other_attributes = false;
387:
388: }
389: }
390:
391: 392: 393: 394: 395:
396: function add_section( $section_name, $args = array() ) {
397: $args = (object)$args;
398:
399: $args->section_name = $section_name;
400: $args->form = $this;
401:
402: if ( ! isset( $args->fields ) )
403: $args->fields = array();
404:
405: if ( ! isset( $args->section_title ) )
406: $args->section_title = false;
407:
408: if ( ! isset( $args->section_handler ) )
409: $args->section_handler = false;
410:
411: return $this->_sections[$section_name] = $args;
412: }
413:
414: 415: 416: 417: 418:
419: function add_field( $field_name, $args = array() ) {
420: if ( 0 == count( $this->_sections ) ) {
421: 422: 423:
424: $section_name = 'default';
425: $this->add_section( $section_name );
426: } else if ( ! isset( $args['section_name'] ) ) {
427: 428: 429:
430: end( $this->_sections );
431: $section_name = key( $this->_sections );
432: } else {
433: 434: 435:
436: $section_name = $args['section_name'];
437: }
438: 439: 440: 441:
442: $args['form'] = $this;
443: $args['plugin'] = $this->plugin;
444: $args['section'] = $this->get_section( $section_name );
445: $field = new Sidecar_Field( $field_name, $args );
446: $this->_fields[$field_name] = &$field;
447: $this->_sections[$section_name]->fields[$field_name] = &$field;
448:
449: $this->get_settings()->register_setting( $field_name );
450:
451: }
452:
453: 454: 455: 456: 457: 458: 459: 460: 461:
462: function get_default_settings_values() {
463: if ( ! isset( $this->_default_settings_values ) ) {
464: $default_settings_values = array();
465: foreach( $this->get_fields() as $field ) {
466: $default_settings_values[$field->field_name] = isset( $field->field_default ) ? $field->field_default : '';
467: }
468: $this->_default_settings_values = $default_settings_values;
469: }
470: return $this->_default_settings_values;
471: }
472:
473: 474: 475:
476: function get_empty_field_values() {
477: return $this->get_settings()->get_empty_field_values();
478: }
479:
480: 481: 482:
483: function get_settings_values() {
484: return $this->get_settings()->get_values();
485: }
486:
487: 488: 489:
490: function get_settings() {
491: if ( ! isset( $this->_settings ) ) {
492: $this->_settings = $this->plugin->get_form_settings( $this->form_name );
493: }
494: return $this->_settings;
495: }
496:
497: 498: 499: 500:
501: function has_setting( $setting_name ) {
502: return $this->get_settings()->has_setting( $setting_name );
503: }
504:
505: 506: 507: 508:
509: function get_setting( $setting_name ) {
510: return $this->get_settings()->get_setting( $setting_name );
511: }
512:
513: 514: 515: 516: 517:
518: function update_settings_value( $setting_name, $value ) {
519: $this->get_settings()->update_settings_value( $setting_name, $value );
520: }
521:
522: 523: 524: 525:
526: function update_settings( $form_settings ) {
527: $this->get_settings()->update_settings( $form_settings );
528: }
529: 530: 531: 532:
533: function update_settings_values( $form_settings ) {
534: $this->get_settings()->set_values( $form_settings );
535: }
536:
537: 538: 539:
540: function get_required_field_names() {
541: if ( ! isset( $this->_required_field_names ) ) {
542: $required_field_names = array();
543: $this->initialize();
544: $form_settings = $this->get_settings();
545: foreach( $this->get_fields() as $field_name => $field ) {
546: if ( $field->field_required && $form_settings->has_setting( $field_name ) ) {
547: $required_field_names[] = $field_name;
548: }
549: }
550: if ( method_exists( $this, 'filter_required_field_names' ) ) {
551: $required_field_names = $this->filter_required_field_names( $required_field_names, $settings );
552: }
553: $this->_required_field_names = $required_field_names;
554: }
555: return $this->_required_field_names;
556: }
557:
558: 559: 560: 561: 562: 563: 564: 565: 566: 567:
568: function ensure_default_values( $field_values ) {
569: foreach( $this->_fields as $field_name => $field ) {
570: if ( ! isset( $field_values[$field_name] ) ) {
571: $field_values[$field_name] = ! is_null( $field->field_default ) ? $field->field_default : false;
572: }
573: }
574: return $field_values;
575: }
576:
577: }
578: