load_dependencies(); $this->page_slug = $page_slug; $this->page_title = $page_title; $this->option_id = $option_id; $this->form = new Phosphor_Backend_Form(); $this->sections = $this->process_sections($this->get_settings_sections()); $this->fields = $this->process_fields($this->get_settings_fields()); $this->options = get_option( $this->option_id ); $this->hidden_fields = array(); $this->register_hooks(); } function load_dependencies() { require_once 'class.backend-form.php'; } public function restore_defaults() { if( !count($_POST) ) return; foreach ($this->sections as $section_id => $section) { if( isset( $_POST[ 'restore-' . $section_id . '-sec' ] ) ) { $_POST[ $this->option_id ][ $section_id ] = $this->init_partial( array(), $this->fields[ $section_id ], true ); } } if( isset($_POST['restore-all']) ) { $_POST[ $this->option_id ] = $this->init_settings( array(), true ); } } /** * Registers hooks with WordPress using add_action() and add_filter() functions. **/ protected function register_hooks() { add_action( 'admin_menu', array($this, 'add_page') ); add_action( 'admin_init', array($this, 'create_options') ); add_action( 'admin_enqueue_scripts', array($this, 'enqueue') ); add_action( 'after_switch_theme', array($this, 'save_default_settings') ); add_action( 'admin_init', array($this, 'restore_defaults'), -999 ); // add_action( 'admin_init', array($this, 'testing_defaults') ); // add_action( 'admin_init', array($this, 'testing_sanitization') ); // add_action( 'admin_init', array($this, 'testing_init') ); } /** * Function for returning an array of settings sections. This needs to be overriden by a child class in order for the options system to work. * * @return array Array of settings sections **/ protected function get_settings_sections(){ die('get_settings_sections() is an abstract function and needs to be overridden by a child class'); } /** * Function for returning an array of settings fields. This needs to be overriden by a child class in order for the options system to work. * * @return array Array of settings sections **/ protected function get_settings_fields() { die('get_settings_fields() is an abstract function and needs to be overridden by a child class'); } /** * This function gets called whenever the theme is activated. It extracts the default values from the fields array and saves them in the options table. **/ public function save_default_settings() { $curr_options = get_option($this->option_id, array()); $curr_options = $this->init_settings( $curr_options ); update_option( $this->option_id, $curr_options ); } /** * Takes an array of options currently saved in the DB and fills in the blanks with default values. It is used by save_default_settings(). * * @var array An array of options. * @return array An array with all the missing items filled with defaults. **/ public function init_settings( $curr_options ){ foreach ($this->fields as $section_key => $section_fields) { $curr_options[ $section_key ] = $this->init_partial( isset( $curr_options[ $section_key ] ) ? $curr_options[ $section_key ] : array(), $section_fields ); } return $curr_options; } /** * Responsible for filling in the blanks with default values. This function is called recursively to take care of nested fields. * * @var array A portion of the original options array. * @var array An array of fields. This could consist of nested fields or the fields in a section. * @return array The first argument with all the missing items filled with defaults. **/ public function init_partial( $current_options, $partial_fields ) { foreach ($partial_fields as $field_id => $field) { if( $this->form->is_nested($field) ){ $sub_fields = isset( $field['items'] ) ? $field['items'] : array(); $current_options[ $field_id ] = $this->init_partial( isset( $current_options[ $field_id ] ) ? $current_options[ $field_id ] : array(), $sub_fields ); } else { // If there is nothing present in the DB against this field's ID then save the default value. // If the field is hidden then overwrite its value in the current options with the default value. // TODO: Empty values are valid so they should be handled properly. if( !isset($current_options[ $field_id ]) || $this->form->is_hidden($field) ){ $current_options[ $field_id ] = $field['def']; } } } return $current_options; } /** * Sanitizes the values input by the user. This function is the callback used in the register_setting() function provided by WordPress. * * @var array The array containing all the values entered by the user. * @return array An array containing sanitized values. **/ public function sanitize_input( $input_items ){ foreach ($this->fields as $section_key => $section_fields) { $input_items[ $section_key ] = $this->sanitize_partial( $input_items[ $section_key ], $section_fields ); } return $input_items; } /** * Sanitizes some user-entered values at a time. This function is called recursively to take care of nested fields. * * @var array An array containing some of the the values entered by the user. * @var array An array of fields corresponding to the values entered by the user. * @return array An array containing sanitized values. **/ public function sanitize_partial( $input_items, $section_fields ){ foreach ($section_fields as $field_id => $field) { if( $this->form->is_nested($field) ){ $sub_fields = isset( $field['items'] ) ? $field['items'] : array(); $input_items[ $field_id ] = $this->sanitize_partial( $input_items[ $field_id ], $sub_fields ); } else { $input_items[ $field_id ] = $this->form->sanitize( $input_items[ $field_id ], $field['type'] ); } } return $input_items; } /** * Adds missing arguments to each settings section in the passed array. * * @var array A 2D array containing the information for all the settings sections. * @return array A modified array in which all the sections have the requred arguments. **/ private function process_sections($sections) { return array_map(array($this, 'set_section_defaults'), $sections); } /** * Uses the wp_parse_args() function to add the missing arguments to a section array. * * @var array An array containing infomation about a single settings section. * @return array The passed array with all the missing items filled in. **/ private function set_section_defaults( $section ){ $defaults = array( 'title' => '', 'callback' => null, 'customizer_section' => false ); return wp_parse_args($section, $defaults); } /** * Adds missing arguments to each field in the passed array. * * @var array A 2D array containing the information for all the fields. In this array fields are grouped by sections. * @return array A modified array in which all the fields have the requred arguments. **/ private function process_fields($fields){ foreach ($fields as $section_key => $section_fields) { $fields[ $section_key ] = $this->process_fields_partial( $fields[ $section_key ] ); } return $fields; } /** * Adds missing arguments to each field in the passed array. This function is called recursively to cater nested fields. * * @var array A 2D array containing the information for all the fields. In this array the fields are not grouped. * @return array A modified array in which all the fields have the requred arguments. **/ private function process_fields_partial( $partial_fields ) { foreach ($partial_fields as $field_key => $field) { $partial_fields[ $field_key ] = $this->form->parse_args($field); if( $this->form->is_nested($field) ){ $sub_fields = isset( $field['items'] ) ? $field['items'] : array(); $partial_fields[ $field_key ]['items'] = $this->process_fields_partial( $sub_fields ); } } return $partial_fields; } public function testing_defaults() { echo "
";
		var_dump( $this->process_sections( $this->get_settings_sections() ) );
		var_dump( $this->process_fields( $this->get_settings_fields() ) );
		echo "
"; die(); } public function testing_sanitization() { if( !count($_POST) ) return; echo "
";
		var_dump( $this->sanitize_input( $_POST[ $this->option_id ] ) );
		echo "
"; die(); } public function testing_init() { echo "
";
		var_dump( $this->init_settings( array() ) );
		echo "
"; die(); } /** * Enqueues the CSS and JS files required for the proper functioning of the plugin. * * @var string $hook The hook of the page currently being viewed by the user. **/ public function enqueue($hook) { if( $this->page_hook != $hook ) return; wp_enqueue_script( "phosphor-op-script" ); wp_enqueue_style( "phosphor-op-styles" ); wp_enqueue_style( "phosphor-fontawesome" ); wp_enqueue_style( "phosphor-jquery-ui" ); } /** * Adds the options page to the admin menu using the add_submenu_page() function. **/ public function add_page() { $this->page_hook = add_theme_page( $this->page_title, // Page Title $this->page_title, // Menu title 'manage_options', // Capability $this->page_slug, // Page slug array($this, 'display') // Callback for displaying the page ); } public function section_callback($section){ ?>
hidden_fields[ $section['id'] ]) ){ foreach ($this->hidden_fields[ $section['id'] ] as $field_args) { $this->form->render( $field_args ); } } ?> sections[ $section['id'] ]['callback'] ) && is_callable( $this->sections[ $section['id'] ]['callback'] ) ? $this->sections[ $section['id'] ]['callback'] : null; if( $user_callback ) { call_user_func( $user_callback, $section ); } } /** * Registers all the settings sections and fields. **/ public function create_options() { $page = $this->option_id; $callback = array($this->form, 'render'); $seperator_count = 0; $end_section = end($this->sections); $sec_callback = array($this, 'section_callback'); reset($this->sections); foreach ($this->sections as $section_id => $section) { $title_prefix = isset( $section['icon'] ) ? sprintf(' ', $section['icon']) : ''; add_settings_section( $section_id, $title_prefix . $section['title'], $sec_callback, $page ); register_setting( $page, $this->option_id, array($this, 'sanitize_input') ); if( is_array( $this->fields[ $section_id ] ) && count( $this->fields[ $section_id ] ) ){ foreach ( $this->fields[ $section_id ] as $field_id => $field ) { $indices = array($section_id, $field_id); $args = array( 'current' => $this->form->get_current_val($this->options, $indices), 'field_name' => $this->form->make_field_name($this->option_id, $indices) ); // If this is a hidden field then render it manually otherwise add a settings field. if( $this->form->is_hidden($field) ){ $this->hidden_fields[ $section_id ][] = array_merge( $field, $args ); } else { add_settings_field( $field_id, $field['title'], $callback, $page, $section_id, array_merge( $field, $args ) ); } } } if( $section != $end_section ){ add_settings_section( 'noid_section_' . $seperator_count, null, array($this, 'section_seperator'), $page ); $seperator_count++; } } } /** * Outputs the contents of the page with the help of WordPress' settings API. **/ public function display(){ ?>

page_title; ?>

option_id ); ?>
option_id ); ?>

display_sidebar(); ?>