PluginProbe
WP Debugging / 2.5.0
WP Debugging v2.5.0
2.12.6 2.12.5 trunk 2.10.0 2.10.1 2.10.2 2.11.0 2.11.1 2.11.10 2.11.11 2.11.12 2.11.13 2.11.14 2.11.15 2.11.16 2.11.17 2.11.18 2.11.19 2.11.2 2.11.20 2.11.21 2.11.22 2.11.23 2.11.24 2.11.3 All 59 releases
wp-debugging / src / Settings.php

Settings.php in WP Debugging 2.5.0, at src/Settings.php

431 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WP Debugging
4 *
5 * @package wp-debugging
6 * @author Andy Fragen
7 * @license MIT
8 */
9
10 namespace Fragen\WP_Debugging;
11
12 /**
13 * Class Settings
14 */
15 class Settings {
16 /**
17 * Hold plugin options.
18 *
19 * @var array
20 */
21 protected static $options;
22
23 /**
24 * Hold `wp-config.php` file path.
25 *
26 * @var string
27 */
28 protected static $config_path;
29
30 /**
31 * Holds pre-defined constants for `wp-config.php`.
32 *
33 * @var array
34 */
35 protected $defined_constants;
36
37 /**
38 * Constructor.
39 *
40 * @param array $options Plugin options.
41 * @param string $config_path Path to config file.
42 * @param array $defined_constants Pre-defined constant group.
43 * @return void
44 */
45 public function __construct( $options, $config_path, $defined_constants ) {
46 self::$options = $options;
47 self::$config_path = $config_path;
48 $this->defined_constants = $defined_constants;
49 }
50
51 /**
52 * Load hooks for settings.
53 *
54 * @return void
55 */
56 public function load_hooks() {
57 add_action( 'admin_init', [ $this, 'add_settings' ] );
58 add_action( is_multisite() ? 'network_admin_menu' : 'admin_menu', [ $this, 'add_plugin_menu' ] );
59 add_action( 'network_admin_edit_wp_debugging', [ $this, 'update_settings' ] );
60 add_action( 'admin_init', [ $this, 'update_settings' ] );
61 add_filter(
62 is_multisite()
63 ? 'network_admin_plugin_action_links_wp-debugging/wp-debugging.php'
64 : 'plugin_action_links_wp-debugging/wp-debugging.php',
65 [ $this, 'plugin_action_links' ]
66 );
67 }
68
69 /**
70 * Add plugin menu.
71 *
72 * @return void
73 */
74 public function add_plugin_menu() {
75 $parent = is_multisite() ? 'settings.php' : 'tools.php';
76 $capability = is_multisite() ? 'manage_network' : 'manage_options';
77
78 add_submenu_page(
79 $parent,
80 esc_html__( 'WP Debugging', 'wp-debugging' ),
81 esc_html__( 'WP Debugging', 'wp-debugging' ),
82 $capability,
83 'wp-debugging',
84 [ $this, 'create_settings_page' ]
85 );
86 }
87
88 /**
89 * Update settings on save.
90 *
91 * @return void
92 */
93 public function update_settings() {
94 if ( isset( $_POST['option_page'] ) &&
95 'wp_debugging' === $_POST['option_page']
96 ) {
97 $options = isset( $_POST['wp-debugging'] )
98 ? $_POST['wp-debugging']
99 : [];
100 $options = self::sanitize( $options );
101 $this->update_constants( self::$options, $options );
102 $filtered_options = array_filter(
103 self::$options,
104 function ( $e ) {
105 return '1' !== $e;
106 }
107 );
108 $options = array_merge( $filtered_options, $options );
109 update_site_option( 'wp_debugging', (array) $options );
110 $this->redirect_on_save();
111 }
112 }
113
114 /**
115 * Update constants in wp-config.php.
116 *
117 * @param array $old Current value of self::$options.
118 * @param mixed $new New value of $options.
119 * @return void
120 */
121 private function update_constants( $old, $new ) {
122 $remove = array_diff_assoc( $old, $new );
123 $add = array_diff_assoc( $new, $old );
124
125 if ( ! empty( $add ) ) {
126 $this->add_constants( $add );
127 }
128 if ( ! empty( $remove ) ) {
129 $this->remove_constants( $remove );
130 }
131 }
132
133 /**
134 * Add constants to wp-config.php file.
135 *
136 * @uses https://github.com/wp-cli/wp-config-transformer
137 *
138 * @param array $add Constants to add to wp-config.php.
139 * @return array $added Array of added constants.
140 */
141 public function add_constants( $add ) {
142 $added = [];
143 $config_transformer = new \WPConfigTransformer( self::$config_path );
144 foreach ( $add as $constant => $config ) {
145 $value = 'wp_debug_display' === $constant ? 'false' : 'true';
146 $value = isset( $config['value'] ) ? $config['value'] : $value;
147 $raw = isset( $config['raw'] ) ? $config['raw'] : true;
148 $config_args = [
149 'raw' => $raw,
150 'normalize' => true,
151 ];
152 $config_transformer->update( 'constant', strtoupper( $constant ), $value, $config_args );
153 $added[ $constant ] = $value;
154 }
155
156 return $added;
157 }
158
159 /**
160 * Process user defined constants added via filter.
161 *
162 * @return void
163 */
164 public function process_filter_constants() {
165 /**
166 * Filter to add user define constants.
167 *
168 * @since 2.5.0
169 *
170 * @param array Array of added constants.
171 * The format for adding constants is to return an array of arrays.
172 * Each array will have the constant as the key with an array of configuration data.
173 * array(
174 * 'my_constant' =>
175 * array(
176 * 'value' => $value, @type string
177 * 'raw' => $raw, // Optional. @type bool $raw is a boolean where false will return the value in quotes and true will return the raw value. Default is true.
178 * ),
179 * )
180 * Default is an empty array.
181 */
182 $filter_constants = apply_filters( 'wp_debugging_add_constants', [] );
183 $remove_user_defined = array_diff( self::$options, array_flip( $this->defined_constants ) );
184
185 // Remove and re-add user defined constants. Clean up for when filter removed or changed.
186 if ( ! empty( $remove_user_defined ) ) {
187 $this->remove_constants( $remove_user_defined );
188 }
189 $added_constants = $this->add_constants( $filter_constants );
190
191 $options = array_diff( self::$options, $remove_user_defined );
192 self::$options = array_merge( $options, $added_constants );
193 update_site_option( 'wp_debugging', (array) self::$options );
194 }
195
196 /**
197 * Remove constants from wp-config.php file.
198 *
199 * @uses https://github.com/wp-cli/wp-config-transformer
200 *
201 * @param array $remove Constants to remove from wp-config.php.
202 * @return void
203 */
204 public function remove_constants( $remove ) {
205 $config_transformer = new \WPConfigTransformer( self::$config_path );
206 foreach ( array_keys( $remove ) as $constant ) {
207 $config_transformer->remove( 'constant', strtoupper( $constant ) );
208 }
209 }
210
211 /**
212 * Redirect back to settings page on save.
213 *
214 * @return void
215 */
216 private function redirect_on_save() {
217 $update = false;
218 if ( ( isset( $_POST['action'] ) && 'update' === $_POST['action'] ) &&
219 ( isset( $_POST['option_page'] ) && 'wp_debugging' === $_POST['option_page'] )
220 ) {
221 $update = true;
222 }
223
224 $redirect_url = is_multisite() ? network_admin_url( 'settings.php' ) : admin_url( 'tools.php' );
225
226 if ( $update ) {
227 $location = add_query_arg(
228 [
229 'page' => 'wp-debugging',
230 'updated' => $update,
231 ],
232 $redirect_url
233 );
234 wp_safe_redirect( $location );
235 exit;
236 }
237 }
238
239 /**
240 * Add notice when settings are saved.
241 *
242 * @return void
243 */
244 private function saved_settings_notice() {
245 if ( ( isset( $_GET['updated'] ) && true == $_GET['updated'] ) ||
246 ( isset( $_GET['settings-updated'] ) && true == $_GET['settings-updated'] )
247 ) {
248 echo '<div class="updated"><p>';
249 esc_html_e( 'Saved.', 'wp-debugging' );
250 echo '</p></div>';
251 }
252 }
253
254 /**
255 * Register settings.
256 *
257 * @return void
258 */
259 public function add_settings() {
260 register_setting(
261 'wp_debugging',
262 'wp_debugging',
263 [ $this, 'sanitize' ]
264 );
265
266 add_settings_section(
267 'wp_debugging',
268 esc_html__( 'Debugging Constants', 'wp-debugging' ),
269 [ $this, 'print_settings_section' ],
270 'wp_debugging'
271 );
272
273 add_settings_field(
274 'wp_debug',
275 null,
276 [ $this, 'checkbox_setting' ],
277 'wp_debugging',
278 'wp_debugging',
279 [
280 'id' => 'wp_debug',
281 'title' => esc_html__( 'Set WP_DEBUG to true.', 'wp-debugging' ),
282 ]
283 );
284
285 add_settings_field(
286 'wp_debug_display',
287 null,
288 [ $this, 'checkbox_setting' ],
289 'wp_debugging',
290 'wp_debugging',
291 [
292 'id' => 'wp_debug_display',
293 'title' => esc_html__( 'Set WP_DEBUG_DISPLAY to false, default is true.', 'wp-debugging' ),
294 ]
295 );
296
297 if ( version_compare( get_bloginfo( 'version' ), '5.2-beta', '>=' ) ) {
298 add_settings_field(
299 'wp_disable_fatal_error_handler',
300 null,
301 [ $this, 'checkbox_setting' ],
302 'wp_debugging',
303 'wp_debugging',
304 [
305 'id' => 'wp_disable_fatal_error_handler',
306 'title' => esc_html__( 'Set WP_DISABLE_FATAL_ERROR_HANDLER to true.', 'wp-debugging' ),
307 ]
308 );
309 }
310
311 $this->process_filter_constants();
312 }
313
314 /**
315 * Print settings section information.
316 *
317 * @return void
318 */
319 public function print_settings_section() {
320 esc_html_e( 'The following constants are set with plugin activation and removed with plugin deactivation.', 'wp-debugging' );
321 $this->print_constants();
322 esc_html_e( 'Select the debugging constants.', 'wp-debugging' );
323 }
324
325 /**
326 * Print current constants.
327 *
328 * @return void
329 */
330 private function print_constants() {
331 $added_constants = apply_filters( 'wp_debugging_add_constants', [] );
332 $additional_constants = [];
333 if ( $added_constants ) {
334 foreach ( $added_constants as $constant => $config ) {
335 $additional_constants[ $constant ] = $config['value'];
336 }
337 }
338
339 // Strip user defined constants from $constants array.
340 $constants = [ 'wp_debug_log', 'script_debug', 'savequeries' ];
341 $constants = array_merge( array_keys( self::$options ), $constants );
342 $constants = array_diff( $constants, array_keys( $additional_constants ) );
343
344 echo '<pre>';
345 foreach ( $constants as $constant ) {
346 $value = 'wp_debug_display' === $constant ? 'false' : 'true';
347 $constant = strtoupper( $constant );
348 echo wp_kses_post( "<code>define( '{$constant}', {$value} );</code><br>" );
349 }
350 foreach ( $additional_constants as $constant => $value ) {
351 $value = in_array( $value, [ 'true', 'false' ], true ) ? $value : "'$value'";
352 $constant = strtoupper( $constant );
353 echo wp_kses_post( "<code>define( '{$constant}', {$value} );</code><br>" );
354 }
355 echo '</pre>';
356 }
357
358 /**
359 * Create settings page.
360 *
361 * @return void
362 */
363 public function create_settings_page() {
364 $this->saved_settings_notice();
365 $action = is_multisite() ? 'edit.php?action=wp-debugging' : 'options.php'; ?>
366 <div class="wrap">
367 <h1><?php esc_html_e( 'WP Debugging', 'wp-debugging' ); ?></h1>
368 <div class="updated fade">
369 <p><?php echo wp_kses_post( __( '<strong>Please note:</strong> Your <code>wp-config.php</code> file must be writable by the filesystem. Any errors will result in a PHP Exception being thrown. Debug constants per <a href="https://codex.wordpress.org/Debugging_in_WordPress">Debugging in WordPress</a>.', 'wp-debugging' ) ); ?></p>
370 </div>
371 <div>
372 <form method="post" action="<?php esc_attr_e( $action ); ?>">
373 <?php settings_fields( 'wp_debugging' ); ?>
374 <?php do_settings_sections( 'wp_debugging' ); ?>
375 <?php submit_button(); ?>
376 </form>
377 </div>
378 <?php
379 }
380
381 /**
382 * Sanitize save settings.
383 *
384 * @param array $input Input.
385 * @return array $new_input Sanitized output.
386 */
387 public function sanitize( $input ) {
388 $new_input = [];
389 if ( ! is_array( $input ) ) {
390 $new_input = sanitize_text_field( $input );
391 } else {
392 foreach ( array_keys( (array) $input ) as $id ) {
393 $new_input[ sanitize_text_field( $id ) ] = sanitize_text_field( $input[ $id ] );
394 }
395 }
396
397 return $new_input;
398 }
399
400 /**
401 * Get the settings option array and print one of its values.
402 *
403 * @param array $args 'id' and 'title'.
404 */
405 public function checkbox_setting( $args ) {
406 $checked = isset( self::$options[ $args['id'] ] ) ? self::$options[ $args['id'] ] : null;
407 ?>
408 <style> .form-table th { display:none; } </style>
409 <label for="<?php esc_attr_e( $args['id'] ); ?>">
410 <input type="checkbox" name="wp-debugging[<?php esc_attr_e( $args['id'] ); ?>]" value="1" <?php checked( '1', $checked ); ?> >
411 <?php esc_html_e( $args['title'] ); ?>
412 </label>
413 <?php
414 }
415
416 /**
417 * Add setting link to plugin page.
418 * Applied to the list of links to display on the plugins page (beside the activate/deactivate links).
419 *
420 * @param array $links Plugin links on plugins.php.
421 *
422 * @return array
423 */
424 public function plugin_action_links( $links ) {
425 $settings_page = is_multisite() ? 'settings.php' : 'tools.php';
426 $link = [ '<a href="' . esc_url( network_admin_url( $settings_page ) ) . '?page=wp-debugging">' . esc_html__( 'Settings', 'wp-debugging' ) . '</a>' ];
427
428 return array_merge( $links, $link );
429 }
430 }
431