WordPress.org

Make WordPress Core

Ticket #18285: 18285.4.diff

File 18285.4.diff, 14.6 KB (added by prettyboymp, 3 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