PluginProbe
Code Snippets / 3.10.1
Code Snippets v3.10.1
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 3.0.1 All 64 releases
code-snippets / php / Admin / Menus / Settings_Menu.php

Settings_Menu.php in Code Snippets 3.10.1, at php/Admin/Menus/Settings_Menu.php

342 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Code_Snippets\Admin\Menus;
4
5 use Code_Snippets\Settings\Settings_Fields;
6 use function Code_Snippets\code_snippets;
7 use function Code_Snippets\Settings\are_settings_unified;
8 use function Code_Snippets\Utils\enqueue_code_editor;
9 use function Code_Snippets\Utils\get_editor_themes;
10 use const Code_Snippets\PLUGIN_FILE;
11 use const Code_Snippets\PLUGIN_VERSION;
12 use const Code_Snippets\Settings\OPTION_GROUP;
13 use const Code_Snippets\Settings\OPTION_NAME;
14 use const Code_Snippets\Settings\CACHE_KEY;
15
16 /**
17 * This class handles the settings admin menu.
18 *
19 * @package Code_Snippets
20 */
21 class Settings_Menu extends Admin_Menu {
22
23 /**
24 * Settings page name as registered with the Settings API.
25 */
26 public const SETTINGS_PAGE = 'code-snippets';
27
28 /**
29 * Constructor.
30 */
31 public function __construct() {
32 parent::__construct(
33 'settings',
34 _x( 'Settings', 'menu label', 'code-snippets' ),
35 __( 'Snippets Settings', 'code-snippets' )
36 );
37 }
38
39 /**
40 * Executed when the admin page is loaded
41 */
42 public function load() {
43 parent::load();
44
45 if ( is_network_admin() ) {
46 if ( are_settings_unified() ) {
47 $this->update_network_options();
48 } else {
49 wp_safe_redirect( code_snippets()->get_menu_url( 'settings', 'admin' ) );
50 exit;
51 }
52 }
53 }
54
55 /**
56 * Enqueue the stylesheet for the settings menu
57 */
58 public function enqueue_assets() {
59 $this->enqueue_codemirror();
60 $handle = 'code-snippets-settings';
61
62 wp_enqueue_style(
63 $handle,
64 plugins_url( 'dist/settings.css', PLUGIN_FILE ),
65 array_merge( self::$style_deps, [ 'code-editor' ] ),
66 PLUGIN_VERSION
67 );
68
69 wp_enqueue_script(
70 $handle,
71 plugins_url( 'dist/settings.js', PLUGIN_FILE ),
72 array_merge( self::$script_deps, [ 'code-snippets-code-editor' ] ),
73 PLUGIN_VERSION,
74 true
75 );
76
77 wp_set_script_translations( $handle, 'code-snippets' );
78 code_snippets()->localize_script( $handle );
79
80 $this->add_codemirror_settings_script( $handle );
81
82 // Provide configuration and simple i18n for the version switch JS module.
83 wp_localize_script(
84 $handle,
85 'code_snippets_version_switch',
86 [
87 'ajaxurl' => admin_url( 'admin-ajax.php' ),
88 'nonce_switch' => wp_create_nonce( 'code_snippets_version_switch' ),
89 'nonce_refresh' => wp_create_nonce( 'code_snippets_refresh_versions' ),
90 ]
91 );
92
93 wp_localize_script(
94 $handle,
95 '__code_snippets_i18n',
96 [
97 'selectDifferent' => esc_html__( 'Please select a different version to switch to.', 'code-snippets' ),
98 'switching' => esc_html__( 'Switching…', 'code-snippets' ),
99 'processing' => esc_html__( 'Processing version switch. Please wait…', 'code-snippets' ),
100 'error' => esc_html__( 'An error occurred.', 'code-snippets' ),
101 'errorSwitch' => esc_html__( 'An error occurred while switching versions. Please try again.', 'code-snippets' ),
102 'refreshing' => esc_html__( 'Refreshing…', 'code-snippets' ),
103 'refreshed' => esc_html__( 'Refreshed!', 'code-snippets' ),
104 ]
105 );
106 }
107
108 /**
109 * Enqueue the CodeMirror scripts and styles, including all themes.
110 *
111 * @return void
112 */
113 protected function enqueue_codemirror() {
114 enqueue_code_editor( 'php' );
115 $themes = get_editor_themes();
116
117 foreach ( $themes as $theme ) {
118 wp_enqueue_style(
119 'code-snippets-editor-theme-' . $theme,
120 plugins_url( "dist/editor-themes/$theme.css", PLUGIN_FILE ),
121 [ 'code-editor' ],
122 PLUGIN_VERSION
123 );
124 }
125 }
126
127 /**
128 * Load the CodeMirror settings as an inline script variable.
129 *
130 * @param string $handle The handle of the script to which the settings will be added.
131 *
132 * @return void
133 */
134 protected function add_codemirror_settings_script( string $handle ) {
135 $field_definitions = Settings_Fields::get_field_definitions();
136 $editor_fields = [];
137
138 foreach ( $field_definitions['editor'] as $name => $field ) {
139 if ( empty( $field['codemirror'] ) ) {
140 continue;
141 }
142
143 $editor_fields[] = [
144 'name' => $name,
145 'type' => $field['type'],
146 'codemirror' => addslashes( $field['codemirror'] ),
147 ];
148 }
149
150 // Pass the saved options to the external JavaScript file.
151 $inline_script = 'var code_snippets_editor_settings = ' . wp_json_encode( $editor_fields ) . ';';
152
153 wp_add_inline_script( $handle, $inline_script, 'before' );
154 }
155
156 /**
157 * Retrieve the list of settings sections.
158 *
159 * @return array<string, array<string, mixed>>
160 */
161 private function get_sections(): array {
162 global $wp_settings_sections;
163
164 if ( ! isset( $wp_settings_sections[ self::SETTINGS_PAGE ] ) ) {
165 return array();
166 }
167
168 return (array) $wp_settings_sections[ self::SETTINGS_PAGE ];
169 }
170
171 /**
172 * Retrieve the name of the settings section currently being viewed.
173 *
174 * @param string $default_section Name of the default tab displayed.
175 *
176 * @return string
177 */
178 public function get_current_section( string $default_section = 'general' ): string {
179 $sections = $this->get_sections();
180
181 if ( ! $sections ) {
182 return $default_section;
183 }
184
185 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Value is matched to registered sections.
186 $active_tab = isset( $_REQUEST['section'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['section'] ) ) : $default_section;
187 return isset( $sections[ $active_tab ] ) ? $active_tab : $default_section;
188 }
189
190 /**
191 * Render the admin screen
192 */
193 public function render() {
194 $this->render_navigation();
195
196 $update_url = is_network_admin() ? add_query_arg( 'update_site_option', true ) : admin_url( 'options.php' );
197 $current_section = $this->get_current_section();
198
199 ?>
200 <div class="wrap code-snippets-settings" data-active-tab="<?php echo esc_attr( $current_section ); ?>">
201 <?php $this->render_section_tabs(); ?>
202
203 <div class="snippets-page-header">
204 <h1><?php esc_html_e( 'Snippets Settings', 'code-snippets' ); ?></h1>
205 </div>
206
207 <?php
208 if ( code_snippets()->is_compact_menu() ) {
209 $actions = [
210 _x( 'Manage', 'snippets', 'code-snippets' ) => code_snippets()->get_menu_url(),
211 _x( 'Add New', 'snippet', 'code-snippets' ) => code_snippets()->get_menu_url( 'add' ),
212 _x( 'Import', 'snippets', 'code-snippets' ) => code_snippets()->get_menu_url( 'import' ),
213 ];
214
215 echo '<p class="settings-page-actions">';
216
217 foreach ( $actions as $label => $url ) {
218 printf(
219 '<a href="%s" class="page-title-action">%s</a>',
220 esc_url( $url ),
221 esc_html( $label )
222 );
223 }
224
225 echo '</p>';
226 }
227 ?>
228
229 <hr class="wp-header-end" />
230
231 <?php settings_errors( OPTION_NAME ); ?>
232
233 <form action="<?php echo esc_url( $update_url ); ?>" method="post">
234 <input type="hidden" name="section" value="<?php echo esc_attr( $current_section ); ?>">
235 <?php
236
237 settings_fields( OPTION_GROUP );
238 $this->render_settings_sections();
239 ?>
240 <p class="submit">
241 <?php
242 submit_button( null, 'primary', 'submit', false );
243
244 submit_button(
245 __( 'Reset to Default', 'code-snippets' ),
246 'secondary',
247 sprintf( '%s[%s]', OPTION_NAME, 'reset_settings' ),
248 false
249 );
250 ?>
251 </p>
252 </form>
253 </div>
254 <?php
255 }
256
257 /**
258 * Output the settings section subnavigation bar, styled to match the
259 * subnavigation on the snippet management pages, followed by the slot
260 * that adopts the Screen Options and Help tabs.
261 */
262 protected function render_section_tabs() {
263 $sections = $this->get_sections();
264 $active_tab = $this->get_current_section();
265
266 echo '<div class="snippet-type-nav-wrapper settings-type-nav-wrapper"><nav class="snippet-type-nav settings-type-nav" id="settings-sections-tabs" aria-label="' . esc_attr__( 'Settings tabs', 'code-snippets' ) . '"><ul>';
267
268 foreach ( $sections as $section ) {
269 printf(
270 '<li><a class="snippet-type-link%s" data-section="%s" href="%s"><span>%s</span></a></li>',
271 esc_attr( $active_tab ) === $section['id'] ? ' active-type' : '',
272 esc_attr( $section['id'] ),
273 esc_url( add_query_arg( 'section', $section['id'] ) ),
274 esc_html( $section['title'] )
275 );
276 }
277
278 echo '</ul></nav></div>';
279 echo '<div id="snippets-screen-meta-slot" class="snippets-screen-meta-slot"></div>';
280 }
281
282 /**
283 * Output snippet settings sections.
284 */
285 protected function render_settings_sections() {
286 $sections = $this->get_sections();
287
288 foreach ( $sections as $section ) {
289 if ( 'license' === $section['id'] ) {
290 continue;
291 }
292
293 if ( $section['title'] ) {
294 printf(
295 '<h2 id="%s-settings" class="settings-section-title">%s</h2>' . "\n",
296 esc_attr( $section['id'] ),
297 esc_html( $section['title'] )
298 );
299 }
300
301 if ( $section['callback'] ) {
302 call_user_func( $section['callback'], $section );
303 }
304
305 printf( '<div class="settings-section %s-settings"><table class="form-table">', esc_attr( $section['id'] ) );
306
307 do_settings_fields( self::SETTINGS_PAGE, $section['id'] );
308 echo '</table></div>';
309 }
310 }
311
312 /**
313 * Fill in for the Settings API in the Network Admin
314 */
315 public function update_network_options() {
316
317 // Ensure the settings have been saved.
318 if ( empty( $_GET['update_site_option'] ) || empty( $_POST[ OPTION_NAME ] ) ) {
319 return;
320 }
321
322 check_admin_referer( 'code-snippets-options' );
323
324 // Retrieve the saved options and save them to the database.
325 $value = map_deep( wp_unslash( $_POST[ OPTION_NAME ] ), 'sanitize_key' );
326 update_site_option( OPTION_NAME, $value );
327 wp_cache_delete( CACHE_KEY );
328
329 // Add an updated notice.
330 if ( ! count( get_settings_errors() ) ) {
331 add_settings_error( 'general', 'settings_updated', __( 'Settings saved.', 'code-snippets' ), 'updated' );
332 }
333
334 set_transient( 'settings_errors', get_settings_errors(), 30 );
335
336 // Redirect back to the settings menu.
337 $redirect = add_query_arg( 'settings-updated', 'true', remove_query_arg( 'update_site_option', wp_get_referer() ) );
338 wp_safe_redirect( esc_url_raw( $redirect ) );
339 exit;
340 }
341 }
342