Overview

Namespaces

  • None
  • PHP

Classes

  • Sidecar
  • Sidecar_Admin_Page
  • Sidecar_Admin_Tab
  • Sidecar_Field
  • Sidecar_Form
  • Sidecar_Form_Settings
  • Sidecar_Plugin_Base
  • Sidecar_Plugin_Settings
  • Sidecar_Settings_Base
  • Sidecar_Shortcode
  • Sidecar_Singleton_Base

Functions

  • body
  • format_gmt_string
  • headers
  • output_css
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download
  1: <?php
  2: /**
  3:  *
  4:  */
  5: class Sidecar_Form {
  6:   /**
  7:    * @var Sidecar_Plugin_Base
  8:    */
  9:   var $plugin;
 10: 
 11:   /**
 12:    * @var Sidecar_Admin_Page
 13:    */
 14:   var $admin_page;
 15: 
 16:   /**
 17:    * @var string
 18:    */
 19:   var $form_name;
 20: 
 21:   /**
 22:    * @var string
 23:    */
 24:   var $form_label;
 25: 
 26:   /**
 27:    * @var bool
 28:    */
 29:   var $requires_api;
 30: 
 31:   /**
 32:    * @var Sidecar_Form_Settings
 33:    */
 34:   private $_settings;
 35: 
 36:   /**
 37:    * @var array
 38:    */
 39:   private $_default_settings_values;
 40: 
 41:   /**
 42:    * @var array
 43:    */
 44:   private $_fields = array();
 45: 
 46:   /**
 47:    * @var array
 48:    */
 49:   private $_sections = array();
 50: 
 51:   /**
 52:    * @var array
 53:    */
 54:   private $_buttons = array();
 55: 
 56:   /**
 57:    * @var bool
 58:    */
 59:   private $_initialized = false;
 60: 
 61:   /**
 62:    * @var array
 63:    */
 64:   private $_required_field_names;
 65: 
 66:   /**
 67:    * @param string $form_name
 68:    * @param array $args
 69:    */
 70:   function __construct( $form_name, $args = array() ) {
 71:     $this->form_name = $form_name;
 72:     /**
 73:      * Copy properties in from $args, if they exist.
 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:    * @return array
 87:    */
 88:   function get_sections() {
 89:     return $this->_sections;
 90:   }
 91: 
 92:   /**
 93:    * @return array
 94:    */
 95:   function get_fields() {
 96:     return $this->_fields;
 97:   }
 98: 
 99:   /**
100:    * @param string $field_name
101:    * @return bool|Sidecar_Field
102:    */
103:   function get_field( $field_name ) {
104:     return isset( $this->_fields[$field_name] ) ? $this->_fields[$field_name] : false;
105:   }
106: 
107:   /**
108:    * @param string $field_name
109:    * @return bool
110:    */
111:   function has_field( $field_name ) {
112:     return isset( $this->_fields[$field_name] );
113:   }
114: 
115:   /**
116:    * @return bool
117:    */
118:   function has_fields() {
119:     return 0 < count( $this->_fields ) ;
120:   }
121: 
122:   /**
123:    * @param string $section_name
124:    * @return bool
125:    */
126:   function get_section( $section_name ) {
127:     return isset( $this->_sections[$section_name] ) ? $this->_sections[$section_name] : false;
128:   }
129: 
130:   /**
131:    * @param string $section_name
132:    * @return bool
133:    */
134:   function has_section( $section_name ) {
135:     return isset( $this->_sections[$section_name] );
136:   }
137: 
138:   /**
139:    * @return bool
140:    */
141:   function has_sections() {
142:     return 0 < count( $this->_sections ) ;
143:   }
144: 
145:   /**
146:    * @param string $section_name
147:    * @return array
148:    */
149:   function get_field_names( $section_name ) {
150:     return array_keys( $this->_sections[$section_name]->fields );
151:   }
152: 
153:   /**
154:    * @param bool|string $section_name
155:    *
156:    * @return bool
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:    * @param bool|string $section_name
168:    *
169:    * @return array
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:    * @return array
181:    */
182:   function the_form() {
183:     echo $this->get_html();
184:     return $this;
185:   }
186: 
187:   /**
188:    * @return string
189:    */
190:   function get_html() {
191:     ob_start();
192:     /**
193:      * Get the HTML for the hidden fields from the Settings API
194:      */
195:     settings_fields( $settings_group = $this->plugin->option_name );
196: 
197:     /**
198:      * Hide hidden fields from Settings API by removing them from global $wp_settings_fields
199:      * Adding to internal $hidden_fields
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:              * @var Sidecar_Field $field_object
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:      * Extract the hidden fields so they won't display
229:      * @var Sidecar_Field $hidden_field
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:      * Output each of the sections.
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:    * @param string  $button_name
288:    * @param string  $button_text
289:    * @param array   $args
290: 
291:    *  string $type The type of button. One of: primary, secondary, delete
292:    *  string $name The HTML name of the submit button. Defaults to "submit". If no id attribute
293:    *               is given in $other_attributes below, $name will be used as the button's id.
294:    *  bool $wrap True if the output button should be wrapped in a paragraph tag,
295:    *               false otherwise. Defaults to true
296:    *  array|string $other_attributes Other attributes that should be output with the button,
297:    *                     mapping attributes to their values, such as array( 'tabindex' => '1' ).
298:    *                     These attributes will be output as attribute="value", such as tabindex="1".
299:    *                     Defaults to no other attributes. Other attributes can also be provided as a
300:    *                     string such as 'tabindex="1"', though the array format is typically cleaner.   */
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:    * @param string $button_name
310:    *
311:    * @return bool
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:    * @param Sidecar_Plugin_Base $plugin
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:    * @param array $args
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:    * @param Sidecar_Plugin_Base $plugin
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:    * @param string  $section_name
393:    * @param array   $args
394:    * @return object
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:    * @param string        $field_name
416:    * @param array         $args
417:    * @return object
418:    */
419:   function add_field( $field_name, $args = array() ) {
420:     if ( 0 == count( $this->_sections ) ) {
421:       /**
422:        * We don't have any sections, set them, to 'default' and register
423:        */
424:       $section_name = 'default';
425:       $this->add_section( $section_name );
426:     } else if ( ! isset( $args['section_name'] ) ) {
427:       /**
428:        * Get the name of the last section added to the sections array.
429:        */
430:       end( $this->_sections );
431:       $section_name = key( $this->_sections );
432:     } else {
433:       /**
434:        * If was passed, grab it.
435:        */
436:       $section_name = $args['section_name'];
437:     }
438:     /**
439:      * Luke, I am your father!
440:      * (or for those who don't get the reference, assign reference to $args['form'] so it will know it's form.)
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:    * Get an array of new setting values (empty string; '').
455:    *
456:    * Override in subclass to add more specific setting defaults.
457:    * @return array
458:    *
459:    * @todo Cache new settings in a setting so that loading from front end does...
460:    * @todo ...require setting the admin form and traversing through these fields.
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:    * @return array
475:    */
476:   function get_empty_field_values() {
477:     return $this->get_settings()->get_empty_field_values();
478:   }
479: 
480:   /**
481:    * @return array
482:    */
483:   function get_settings_values() {
484:     return $this->get_settings()->get_values();
485:   }
486: 
487:   /**
488:    * @return Sidecar_Form_Settings
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:    * @param string $setting_name
499:    * @return bool
500:    */
501:   function has_setting( $setting_name ) {
502:     return $this->get_settings()->has_setting( $setting_name );
503:   }
504: 
505:   /**
506:    * @param string $setting_name
507:    * @return mixed
508:    */
509:   function get_setting( $setting_name ) {
510:     return $this->get_settings()->get_setting( $setting_name );
511:     }
512: 
513:   /**
514:    * @param string $setting_name
515:    * @param mixed $value
516:    * @return array
517:    */
518:   function update_settings_value( $setting_name, $value ) {
519:     $this->get_settings()->update_settings_value( $setting_name, $value );
520:   }
521: 
522:   /**
523:    * @param array $form_settings
524:    * @return array
525:    */
526:   function update_settings( $form_settings ) {
527:     $this->get_settings()->update_settings( $form_settings );
528:   }
529:   /**
530:    * @param array $form_settings
531:    * @return array
532:    */
533:   function update_settings_values( $form_settings ) {
534:     $this->get_settings()->set_values( $form_settings );
535:   }
536: 
537:   /**
538:    * @return array
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:    * Ensure their is a default value for every field w/o a matching array element.
560:    *
561:    * This is used to ensure forms POSTed back always have all fields. In cases of
562:    * checkboxes or radio buttons they may not.
563:    *
564:    * @param array $field_values
565:    *
566:    * @return array
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: 
API documentation generated by ApiGen 2.8.0