WordPress.org

Make WordPress Core

Ticket #18285: 18285.4.diff

File 18285.4.diff, 14.6 KB (added by prettyboymp, 7 years ago)

updates to current settings api to simplify field creation

  • wp-admin/includes/plugin.php

     
    868868
    869869        $menu_slug = plugin_basename( $menu_slug );
    870870
     871        if( isset( $admin_page_hooks[ $menu_slug ] ) ) {
     872                $hookname = get_plugin_page_hookname( $menu_slug, '' );
     873                //Avoid registering the same hook twice. Note that any later registrations won't get the display action automatically added to avoid complete page from being rendered twice
     874                return $hookname;
     875        }
     876
    871877        $admin_page_hooks[$menu_slug] = sanitize_title( $menu_title );
    872878
    873879        $hookname = get_plugin_page_hookname( $menu_slug, '' );
     
    17151721 *
    17161722 * @since 2.7.0
    17171723 *
    1718  * @param string $option_group A settings group name.  This should match the group name used in register_setting().
     1724 * @param string $page_id The slug name of the settings page.  This should match the group name used in register_setting().
    17191725 */
    1720 function settings_fields($option_group) {
    1721         echo "<input type='hidden' name='option_page' value='" . esc_attr($option_group) . "' />";
     1726function settings_fields($page_id) {
     1727        echo "<input type='hidden' name='option_page' value='" . esc_attr($page_id) . "' />";
    17221728        echo '<input type="hidden" name="action" value="update" />';
    1723         wp_nonce_field("$option_group-options");
     1729        wp_nonce_field("$page_id-options");
    17241730}
    17251731
    17261732?>
  • wp-admin/includes/template.php

     
    10781078 *
    10791079 * @global $wp_settings_sections Storage array of all settings sections added to admin pages
    10801080 *
    1081  * @param string $id Slug-name to identify the section. Used in the 'id' attribute of tags.
     1081 * @param string $section_id Slug-name to identify the section. Used in the 'id' attribute of tags.
    10821082 * @param string $title Formatted title of the section. Shown as the heading for the section.
    1083  * @param string $callback Function that echos out any content at the top of the section (between heading and fields).
    1084  * @param string $page The slug-name of the settings page on which to show the section. Built-in pages include 'general', 'reading', 'writing', 'discussion', 'media', etc. Create your own using add_options_page();
     1083 * @param string $pre_callback Function that echos out any content at the top of the section (between heading and fields).
     1084 * @param string $page_id The slug-name of the settings page on which to show the section. Built-in pages include 'general', 'reading', 'writing', 'discussion', 'media', etc. Create your own using add_options_page();
    10851085 */
    1086 function add_settings_section($id, $title, $callback, $page) {
     1086function add_settings_section( $section_id, $title = '', $pre_callback = '', $page_id ) {
    10871087        global $wp_settings_sections;
    10881088
    1089         if ( 'misc' == $page ) {
     1089        //leaving this in for now in case we don't change this function much
     1090        if( 'misc' == $page_id ) {
    10901091                _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
    1091                 $page = 'general';
     1092                $page_id = 'general';
    10921093        }
    10931094
    1094         if ( !isset($wp_settings_sections) )
     1095        if( !isset( $wp_settings_sections ) )
    10951096                $wp_settings_sections = array();
    1096         if ( !isset($wp_settings_sections[$page]) )
    1097                 $wp_settings_sections[$page] = array();
    1098         if ( !isset($wp_settings_sections[$page][$id]) )
    1099                 $wp_settings_sections[$page][$id] = array();
     1097        if( !isset( $wp_settings_sections[$page_id] ) )
     1098                $wp_settings_sections[$page_id] = array();
     1099        if( isset( $wp_settings_sections[$page_id][$section_id] ) )
     1100                return; //avoid overwriting the previous registration and adding additional pre-section callback.  If output other than a description is needed before the section, the action can be hooked into on it's own
    11001101
    1101         $wp_settings_sections[$page][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback);
     1102                $wp_settings_sections[$page_id][$section_id] = array('id' => $section_id, 'title' => $title);
     1103
     1104        if( $pre_callback )
     1105                add_action( "pre_setting_section_{$page_id}_{$section_id}", $pre_callback );
    11021106}
    11031107
    11041108/**
     
    11161120 *
    11171121 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
    11181122 *
    1119  * @param string $id Slug-name to identify the field. Used in the 'id' attribute of tags.
     1123 * @param string $field_id Slug-name to identify the field. Used in the 'id' attribute of tags.
    11201124 * @param string $title Formatted title of the field. Shown as the label for the field during output.
    1121  * @param string $callback Function that fills the field with the desired form inputs. The function should echo its output.
    1122  * @param string $page The slug-name of the settings page on which to show the section (general, reading, writing, ...).
    1123  * @param string $section The slug-name of the section of the settingss page in which to show the box (default, ...).
     1125 * @param string $display_callback Function that fills the field with the desired form inputs. The function should echo its output.
     1126 * @param string $page_id The slug-name of the settings page on which to show the section (general, reading, writing, ...).
     1127 * @param string $section_id The slug-name of the section of the settingss page in which to show the box (default, ...).
    11241128 * @param array $args Additional arguments
     1129 * @param string $sanitize_callback Function that sanitizes the field on save
     1130 * @param string $option_name Optional name of otion that will be updated from the field, will use the field_id if not set.
    11251131 */
    1126 function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) {
     1132function add_settings_field($field_id, $title, $display_callback, $page_id, $section_id = 'default', $args = array(), $sanitize_callback = '', $option_name = '' ) {
    11271133        global $wp_settings_fields;
    11281134
    1129         if ( 'misc' == $page ) {
     1135        if ( 'misc' == $page_id ) {
    11301136                _deprecated_argument( __FUNCTION__, '3.0', __( 'The miscellaneous options group has been removed. Use another settings group.' ) );
    1131                 $page = 'general';
     1137                $page_id = 'general';
    11321138        }
    11331139
    1134         if ( !isset($wp_settings_fields) )
    1135                 $wp_settings_fields = array();
    1136         if ( !isset($wp_settings_fields[$page]) )
    1137                 $wp_settings_fields[$page] = array();
    1138         if ( !isset($wp_settings_fields[$page][$section]) )
    1139                 $wp_settings_fields[$page][$section] = array();
     1140        //we set the field data here because I want the option_name to still be empty if it wasn't passed in
     1141        if( $option_name )
     1142                $the_option_name = $option_name;
     1143        else
     1144                $the_option_name = $field_id;
    11401145
    1141         $wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args);
     1146        if( !isset( $wp_settings_fields ) )
     1147                $wp_settings_fields = array( );
     1148        if( !isset( $wp_settings_fields[ $page_id ] ) )
     1149                $wp_settings_fields[ $page_id ] = array( );
     1150        if( !isset( $wp_settings_fields[ $page_id ][ $section_id ] ) )
     1151                $wp_settings_fields[ $page_id ][ $section_id ] = array( );
     1152
     1153        if( !isset( $wp_settings_fields[ $page_id ][ $section_id ][ $the_option_name ] ) )
     1154                $wp_settings_fields[ $page_id ][ $section_id ][ $the_option_name ] = array( );
     1155
     1156        if( !isset( $wp_settings_fields[ $page_id ][ $section_id ][ $the_option_name ][ $field_id ] ) )
     1157                $wp_settings_fields[ $page_id ][ $section_id ][ $the_option_name ][ $field_id ] = array( 'id' => $field_id, 'title' => $title, 'callback' => $display_callback, 'args' => $args, 'option_name' => $option_name ); //don't override a previously registered field
     1158
     1159        if( $sanitize_callback )
     1160                add_filter( "sanitize_setting_{$page_id}_{$section_id}_{$field_id}", $sanitize_callback, 10, 3 );       //args planned to be $new_value, $old_value, $args from previous
    11421161}
    11431162
    11441163/**
     
    11521171 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
    11531172 * @since 2.7.0
    11541173 *
    1155  * @param string $page The slug name of the page whos settings sections you want to output
     1174 * @param string $page_id The slug name of the page whos settings sections you want to output
    11561175 */
    1157 function do_settings_sections($page) {
     1176function do_settings_sections($page_id) {
    11581177        global $wp_settings_sections, $wp_settings_fields;
    11591178
    1160         if ( !isset($wp_settings_sections) || !isset($wp_settings_sections[$page]) )
     1179        if( !isset( $wp_settings_sections ) || !isset( $wp_settings_sections[ $page_id ] ) )
    11611180                return;
    11621181
    1163         foreach ( (array) $wp_settings_sections[$page] as $section ) {
    1164                 if ( $section['title'] )
    1165                         echo "<h3>{$section['title']}</h3>\n";
    1166                 call_user_func($section['callback'], $section);
    1167                 if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section['id']]) )
    1168                         continue;
    1169                 echo '<table class="form-table">';
    1170                 do_settings_fields($page, $section['id']);
    1171                 echo '</table>';
     1182        foreach( ( array ) $wp_settings_sections[ $page_id ] as $section ) {
     1183                if( $section[ 'title' ] )
     1184                        echo "<h3>{$section[ 'title' ]}</h3>\n";
     1185
     1186                do_action( "pre_setting_section_{$page_id}_{$section[ 'id' ]}" );
     1187
     1188                if( isset( $wp_settings_fields ) && isset( $wp_settings_fields[ $page_id ] ) && isset( $wp_settings_fields[ $page_id ][ $section[ 'id' ] ] ) ) {
     1189                        echo '<table class="form-table">';
     1190                        do_settings_fields( $page_id, $section[ 'id' ] );
     1191                        echo '</table>';
     1192                }
     1193                do_action( "post_setting_section_{$page_id}_{$section[ 'id' ]}" );
    11721194        }
    11731195}
    11741196
     
    11861208 * @param string $page Slug title of the admin page who's settings fields you want to show.
    11871209 * @param section $section Slug title of the settings section who's fields you want to show.
    11881210 */
    1189 function do_settings_fields($page, $section) {
     1211function do_settings_fields( $page_id, $section_id ) {
    11901212        global $wp_settings_fields;
    11911213
    1192         if ( !isset($wp_settings_fields) || !isset($wp_settings_fields[$page]) || !isset($wp_settings_fields[$page][$section]) )
     1214        if( !isset( $wp_settings_fields ) || !isset( $wp_settings_fields[ $page_id ] ) || !isset( $wp_settings_fields[ $page_id ][ $section_id ] ) )
    11931215                return;
    11941216
    1195         foreach ( (array) $wp_settings_fields[$page][$section] as $field ) {
    1196                 echo '<tr valign="top">';
    1197                 if ( !empty($field['args']['label_for']) )
    1198                         echo '<th scope="row"><label for="' . $field['args']['label_for'] . '">' . $field['title'] . '</label></th>';
    1199                 else
    1200                         echo '<th scope="row">' . $field['title'] . '</th>';
    1201                 echo '<td>';
    1202                 call_user_func($field['callback'], $field['args']);
    1203                 echo '</td>';
    1204                 echo '</tr>';
     1217        foreach( ( array ) $wp_settings_fields[ $page_id ][ $section_id ] as $option_group ) {  //downside here obviously is that items that share option_names have to be grouped
     1218                foreach( ( array ) $option_group as $field ) {
     1219                        echo '<tr valign="top">';
     1220                        if( !empty( $field[ 'args' ][ 'label_for' ] ) )
     1221                                echo '<th scope="row"><label for="' . $field[ 'args' ][ 'label_for' ] . '">' . $field[ 'title' ] . '</label></th>';
     1222                        else
     1223                                echo '<th scope="row">' . $field[ 'title' ] . '</th>';
     1224                        echo '<td>';
     1225                        if( empty( $field[ 'option_name' ] ) )
     1226                                $current_value = get_option( $field[ 'id' ] );
     1227                        else {
     1228                                $option_value = get_option( $field[ 'option_name' ] );
     1229                                if( is_array( $option_value ) && isset( $option_value[ $field[ 'id' ] ] ) )
     1230                                        $current_value = $option_value[ $field[ 'id' ] ];
     1231                                else
     1232                                        $current_value = false;
     1233                        }
     1234                        call_user_func( $field[ 'callback' ], $field[ 'args' ], $current_value, $field, $section_id, $page_id );
     1235                        echo '</td>';
     1236                        echo '</tr>';
     1237                }
    12051238        }
    12061239}
    12071240
    12081241/**
     1242 * Saves the registered settings fields for the given page_id
     1243 *
     1244 * Part of the Settings API.  This method should be called on 'load-{$page_slug}'
     1245 * to save any fields that have been registered for that page.
     1246 *
     1247 * @global $wp_settings_fields $wp_settings_fields
     1248 * @staticvar array $saved_settings_pages
     1249 *
     1250 * @since 3.3
     1251 *
     1252 * @param string $page_id slug name of the page to identify the page used for the settings
     1253 */
     1254function save_settings_page( $page_id ) {
     1255        global $wp_settings_fields;
     1256
     1257        static $saved_settings_pages = array( ); //local storage to keep pages from being processed multiple times
     1258
     1259        if( !isset( $saved_settings_pages[ $page_id ] ) && isset( $wp_settings_fields[ $page_id ] ) && is_array( $wp_settings_fields[ $page_id ] ) ) {
     1260                foreach( $wp_settings_fields[ $page_id ] as $section_id => $section ) {
     1261                        if( is_array( $section ) ) {
     1262                                foreach( $section as $option_name => $fields ) {
     1263                                        $option_value = get_option( $option_name );
     1264                                        if( is_array( $fields ) && count( $fields ) ) {
     1265                                                if( 1 === count( $fields ) && isset( $fields[ $option_name ] ) && $fields[ $option_name ][ 'id' ] == $option_name ) {
     1266                                                        //if there is only one field for the option and it matches the option_name, this is a singular option
     1267                                                        $new_value = isset( $_POST[ $fields[ $option_name ][ 'id' ] ] ) ? $_POST[ $fields[ $option_name ][ 'id' ] ] : false;
     1268                                                        $option_value = apply_filters( "sanitize_setting_{$page_id}_{$section_id}_{$fields[ $option_name ][ 'id' ]}", $new_value, $option_value, $fields[ $option_name ] );
     1269                                                } else {
     1270                                                        //this is an set of fields stored under one option
     1271                                                        if( !is_array( $option_value ) )
     1272                                                                $option_value = array( );
     1273
     1274                                                        foreach( $fields as $field ) {
     1275                                                                $new_value = isset( $_POST[ $field[ 'id' ] ] ) ? $_POST[ $field[ 'id' ] ] : false;
     1276                                                                $old_value = isset( $option_value[ $field[ 'id' ] ] ) ? $option_value[ $field[ 'id' ] ] : false;
     1277                                                                $option_value[ $field[ 'id' ] ] = apply_filters( "sanitize_setting_{$page_id}_{$section_id}_{$field[ 'id' ]}", $new_value, $old_value, $field );
     1278                                                        }
     1279                                                }
     1280                                                update_option( $option_name, $option_value );
     1281                                        }
     1282                                }
     1283                        }
     1284                }
     1285                $saved_settings_pages[ $page_id ] = true;
     1286        }
     1287        if( !count( get_settings_errors( $page_id ) ) )
     1288                add_settings_error( $page_id, 'settings_updated', __( 'Settings saved.' ), 'updated' );
     1289}
     1290
     1291/**
    12091292 * Register a settings error to be displayed to the user
    12101293 *
    12111294 * Part of the Settings API. Use this to show messages to users about settings validation
     
    13121395 *
    13131396 * @since 3.0.0
    13141397 *
    1315  * @param string $setting Optional slug title of a specific setting who's errors you want.
     1398 * @param string $page_id Optional slug title of a specific setting page who's errors you want.
    13161399 * @param boolean $sanitize Whether to re-sanitize the setting value before returning errors.
    13171400 * @param boolean $hide_on_update If set to true errors will not be shown if the settings page has already been submitted.
    13181401 */
    1319 function settings_errors( $setting = '', $sanitize = FALSE, $hide_on_update = FALSE ) {
     1402function settings_errors( $page_id = '', $sanitize = FALSE, $hide_on_update = FALSE ) {
    13201403
    13211404        if ($hide_on_update AND $_GET['settings-updated']) return;
    13221405
    1323         $settings_errors = get_settings_errors( $setting, $sanitize );
     1406        $settings_errors = get_settings_errors( $page_id, $sanitize );
    13241407
    13251408        if ( !is_array($settings_errors) ) return;
    13261409