PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
← All changes | php/Settings/settings.php +105 -22 3.10.24.0.0-beta.2 View file →
@@ -98,25 +98,80 @@
98 98 return update_self_option( are_settings_unified(), OPTION_NAME, $settings );
99 99 }
100 100
101 101 /**
102 + * Render the fields of a settings section, with group headings.
103 + *
104 + * Mirrors the core `do_settings_fields()`, adding a full-width heading row
105 + * above any field carrying a `group_heading` argument. Tabs are long enough
106 + * that unbroken rows are hard to scan.
107 + *
108 + * @param string $page Settings page slug.
109 + * @param string $section Settings section identifier.
110 + *
111 + * @return void
112 + */
113 +function do_settings_fields_with_headings( string $page, string $section ): void {
114 + global $wp_settings_fields;
115 +
116 + if ( ! isset( $wp_settings_fields[ $page ][ $section ] ) ) {
117 + return;
118 + }
119 +
120 + $seen_headings = [];
121 +
122 + foreach ( (array) $wp_settings_fields[ $page ][ $section ] as $field ) {
123 + $heading = $field['args']['group_heading'] ?? '';
124 +
125 + // A heading is skipped if an identical one has already been drawn, so
126 + // that a group whose first field is absent does not repeat it.
127 + if ( $heading && ! in_array( $heading, $seen_headings, true ) ) {
128 + $seen_headings[] = $heading;
129 + printf(
130 + '<tr class="settings-group-heading"><th colspan="2" scope="colgroup">%s</th></tr>',
131 + esc_html( $heading )
132 + );
133 + }
134 +
135 + $class = empty( $field['args']['class'] ) ? '' : ' class="' . esc_attr( $field['args']['class'] ) . '"';
136 +
137 + echo '<tr' . $class . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped above.
138 +
139 + // A field with no title, such as a notice rendered by a callback, spans
140 + // the row rather than leaving an empty header cell for a screen reader.
141 + if ( '' === (string) $field['title'] ) {
142 + echo '<td colspan="2">';
143 + call_user_func( $field['callback'], $field['args'] );
144 + echo '</td></tr>';
145 + continue;
146 + }
147 +
148 + if ( ! empty( $field['args']['label_for'] ) ) {
149 + printf(
150 + '<th scope="row"><label for="%s">%s</label></th>',
151 + esc_attr( $field['args']['label_for'] ),
152 + esc_html( $field['title'] )
153 + );
154 + } else {
155 + printf( '<th scope="row">%s</th>', esc_html( $field['title'] ) );
156 + }
157 +
158 + echo '<td>';
159 + call_user_func( $field['callback'], $field['args'] );
160 + echo '</td></tr>';
161 + }
162 +}
163 +
164 +/**
102 165 * Retrieve the settings sections
103 166 *
104 167 * @return array<string, string> Settings sections.
105 168 */
106 169 function get_settings_sections(): array {
107 - $sections = array(
108 - 'general' => __( 'General', 'code-snippets' ),
109 - 'editor' => __( 'Code Editor', 'code-snippets' ),
110 - 'debug' => __( 'Debug', 'code-snippets' ),
111 - );
170 + // Tabs are grouped by task rather than by storage section. Values still
171 + // save into their original sections; see Settings_Layout.
172 + $sections = Settings_Layout::get_available_tabs();
112 173
113 - // Only show the Version section when the debug setting to enable version changes is enabled.
114 - $enable_version = get_setting( 'debug', 'enable_version_change' );
115 - if ( $enable_version ) {
116 - $sections['version-switch'] = __( 'Version', 'code-snippets' );
117 - }
118 -
119 174 return apply_filters( 'code_snippets_settings_sections', $sections );
120 175 }
121 176
122 177 /**
@@ -140,22 +195,50 @@
140 195 foreach ( get_settings_sections() as $section_id => $section_name ) {
141 196 add_settings_section( $section_id, $section_name, '__return_empty_string', 'code-snippets' );
142 197 }
143 198
144 - // Register settings fields. Only register fields for sections that exist (some sections may be gated by settings).
145 - $registered_sections = get_settings_sections();
146 - foreach ( Settings_Fields::get_field_definitions() as $section_id => $fields ) {
147 - if ( ! isset( $registered_sections[ $section_id ] ) ) {
148 - continue;
149 - }
199 + // Register settings fields. The tab a field appears under comes from the
200 + // layout, while the section it saves into stays exactly as it was.
201 + $definitions = Settings_Fields::get_field_definitions();
202 + $descriptions = Settings_Layout::get_descriptions();
203 + $headings = Settings_Layout::get_group_headings();
150 204
151 - foreach ( $fields as $field_id => $field ) {
152 - if ( ! should_render_setting_field( $field, $current_settings ) ) {
153 - continue;
205 + foreach ( get_settings_sections() as $tab_id => $tab_name ) {
206 + foreach ( Settings_Layout::get_visible_fields( $tab_id, $current_settings ) as $entry ) {
207 + list( $section_id, $field_id ) = $entry;
208 + $field = $definitions[ $section_id ][ $field_id ];
209 +
210 + // Reword the settings whose description names the control without
211 + // saying what it buys you.
212 + if ( isset( $descriptions[ $field_id ] ) ) {
213 + $field['desc'] = $descriptions[ $field_id ];
154 214 }
155 215
156 216 $field_object = new Setting_Field( $section_id, $field_id, $field );
157 - add_settings_field( $field_id, $field['name'], [ $field_object, 'render' ], 'code-snippets', $section_id );
217 +
218 + // Field types that render a single labelable control get their table
219 + // heading turned into a real <label for>, giving the control an
220 + // accessible name. Checkboxes render their own labels, and
221 + // callback/action fields have no single control to point at.
222 + $labelable_types = [ 'text', 'number', 'select' ];
223 + $field_args = [];
224 +
225 + if ( isset( $field['type'] ) && in_array( $field['type'], $labelable_types, true ) ) {
226 + $field_args['label_for'] = $field_object->element_id;
227 + }
228 +
229 + if ( isset( $headings[ $tab_id ][ $field_id ] ) ) {
230 + $field_args['group_heading'] = $headings[ $tab_id ][ $field_id ];
231 + }
232 +
233 + add_settings_field(
234 + $field_id,
235 + $field['name'],
236 + [ $field_object, 'render' ],
237 + 'code-snippets',
238 + $tab_id,
239 + $field_args
240 + );
158 241 }
159 242 }
160 243
161 244 $editor_preview = new Editor_Preview();
@@ -165,9 +248,9 @@
165 248 'editor_preview',
166 249 __( 'Editor Preview', 'code-snippets' ),
167 250 [ $editor_preview, 'render' ],
168 251 'code-snippets',
169 - 'editor'
252 + 'editing'
170 253 );
171 254
172 255 Version_Switch::init();
173 256 }