PluginProbe
WP Debugging / 2.5.7
WP Debugging v2.5.7
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.7, at src/Settings.php

439 lines 12.0 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 if ( ! file_exists( self::$config_path ) || \filesize( self::$config_path ) ) {
143 return [];
144 }
145
146 $added = [];
147 $config_transformer = new \WPConfigTransformer( self::$config_path );
148 foreach ( $add as $constant => $config ) {
149 $value = 'wp_debug_display' === $constant ? 'false' : 'true';
150 $value = isset( $config['value'] ) ? $config['value'] : $value;
151 $raw = isset( $config['raw'] ) ? $config['raw'] : true;
152 $config_args = [
153 'raw' => $raw,
154 'normalize' => true,
155 ];
156 $config_transformer->update( 'constant', strtoupper( $constant ), $value, $config_args );
157 $added[ $constant ] = $value;
158 }
159
160 return $added;
161 }
162
163 /**
164 * Process user defined constants added via filter.
165 *
166 * @return void
167 */
168 public function process_filter_constants() {
169 /**
170 * Filter to add user define constants.
171 *
172 * @since 2.5.0
173 *
174 * @param array Array of added constants.
175 * The format for adding constants is to return an array of arrays.
176 * Each array will have the constant as the key with an array of configuration data.
177 * array(
178 * 'my_constant' =>
179 * array(
180 * 'value' => $value, @type string
181 * '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.
182 * ),
183 * )
184 * Default is an empty array.
185 */
186 $filter_constants = apply_filters( 'wp_debugging_add_constants', [] );
187 $remove_user_defined = array_diff( self::$options, array_flip( $this->defined_constants ) );
188
189 // Remove and re-add user defined constants. Clean up for when filter removed or changed.
190 if ( ! empty( $remove_user_defined ) ) {
191 $this->remove_constants( $remove_user_defined );
192 }
193 $added_constants = $this->add_constants( $filter_constants );
194
195 $options = array_diff( self::$options, $remove_user_defined );
196 self::$options = array_merge( $options, $added_constants );
197 update_site_option( 'wp_debugging', (array) self::$options );
198 }
199
200 /**
201 * Remove constants from wp-config.php file.
202 *
203 * @uses https://github.com/wp-cli/wp-config-transformer
204 *
205 * @param array $remove Constants to remove from wp-config.php.
206 * @return void
207 */
208 public function remove_constants( $remove ) {
209 if ( ! file_exists( self::$config_path ) || \filesize( self::$config_path ) ) {
210 return;
211 }
212
213 $config_transformer = new \WPConfigTransformer( self::$config_path );
214 foreach ( array_keys( $remove ) as $constant ) {
215 $config_transformer->remove( 'constant', strtoupper( $constant ) );
216 }
217 }
218
219 /**
220 * Redirect back to settings page on save.
221 *
222 * @return void
223 */
224 private function redirect_on_save() {
225 $update = false;
226 if ( ( isset( $_POST['action'] ) && 'update' === $_POST['action'] ) &&
227 ( isset( $_POST['option_page'] ) && 'wp_debugging' === $_POST['option_page'] )
228 ) {
229 $update = true;
230 }
231
232 $redirect_url = is_multisite() ? network_admin_url( 'settings.php' ) : admin_url( 'tools.php' );
233
234 if ( $update ) {
235 $location = add_query_arg(
236 [
237 'page' => 'wp-debugging',
238 'updated' => $update,
239 ],
240 $redirect_url
241 );
242 wp_safe_redirect( $location );
243 exit;
244 }
245 }
246
247 /**
248 * Add notice when settings are saved.
249 *
250 * @return void
251 */
252 private function saved_settings_notice() {
253 if ( ( isset( $_GET['updated'] ) && true == $_GET['updated'] ) ||
254 ( isset( $_GET['settings-updated'] ) && true == $_GET['settings-updated'] )
255 ) {
256 echo '<div class="updated"><p>';
257 esc_html_e( 'Saved.', 'wp-debugging' );
258 echo '</p></div>';
259 }
260 }
261
262 /**
263 * Register settings.
264 *
265 * @return void
266 */
267 public function add_settings() {
268 register_setting(
269 'wp_debugging',
270 'wp_debugging',
271 [ $this, 'sanitize' ]
272 );
273
274 add_settings_section(
275 'wp_debugging',
276 esc_html__( 'Debugging Constants', 'wp-debugging' ),
277 [ $this, 'print_settings_section' ],
278 'wp_debugging'
279 );
280
281 add_settings_field(
282 'wp_debug',
283 null,
284 [ $this, 'checkbox_setting' ],
285 'wp_debugging',
286 'wp_debugging',
287 [
288 'id' => 'wp_debug',
289 'title' => esc_html__( 'Set WP_DEBUG to true.', 'wp-debugging' ),
290 ]
291 );
292
293 add_settings_field(
294 'wp_debug_display',
295 null,
296 [ $this, 'checkbox_setting' ],
297 'wp_debugging',
298 'wp_debugging',
299 [
300 'id' => 'wp_debug_display',
301 'title' => esc_html__( 'Set WP_DEBUG_DISPLAY to false, default is true.', 'wp-debugging' ),
302 ]
303 );
304
305 if ( version_compare( get_bloginfo( 'version' ), '5.2-beta', '>=' ) ) {
306 add_settings_field(
307 'wp_disable_fatal_error_handler',
308 null,
309 [ $this, 'checkbox_setting' ],
310 'wp_debugging',
311 'wp_debugging',
312 [
313 'id' => 'wp_disable_fatal_error_handler',
314 'title' => esc_html__( 'Set WP_DISABLE_FATAL_ERROR_HANDLER to true.', 'wp-debugging' ),
315 ]
316 );
317 }
318
319 $this->process_filter_constants();
320 }
321
322 /**
323 * Print settings section information.
324 *
325 * @return void
326 */
327 public function print_settings_section() {
328 esc_html_e( 'The following constants are set with plugin activation and removed with plugin deactivation.', 'wp-debugging' );
329 $this->print_constants();
330 esc_html_e( 'Select the debugging constants.', 'wp-debugging' );
331 }
332
333 /**
334 * Print current constants.
335 *
336 * @return void
337 */
338 private function print_constants() {
339 $added_constants = apply_filters( 'wp_debugging_add_constants', [] );
340 $additional_constants = [];
341 if ( $added_constants ) {
342 foreach ( $added_constants as $constant => $config ) {
343 $additional_constants[ $constant ] = $config['value'];
344 }
345 }
346
347 // Strip user defined constants from $constants array.
348 $constants = [ 'wp_debug_log', 'script_debug', 'savequeries' ];
349 $constants = array_merge( array_keys( self::$options ), $constants );
350 $constants = array_diff( $constants, array_keys( $additional_constants ) );
351
352 echo '<pre>';
353 foreach ( $constants as $constant ) {
354 $value = 'wp_debug_display' === $constant ? 'false' : 'true';
355 $constant = strtoupper( $constant );
356 echo wp_kses_post( "<code>define( '{$constant}', {$value} );</code><br>" );
357 }
358 foreach ( $additional_constants as $constant => $value ) {
359 $value = in_array( $value, [ 'true', 'false' ], true ) ? $value : "'$value'";
360 $constant = strtoupper( $constant );
361 echo wp_kses_post( "<code>define( '{$constant}', {$value} );</code><br>" );
362 }
363 echo '</pre>';
364 }
365
366 /**
367 * Create settings page.
368 *
369 * @return void
370 */
371 public function create_settings_page() {
372 $this->saved_settings_notice();
373 $action = is_multisite() ? 'edit.php?action=wp-debugging' : 'options.php'; ?>
374 <div class="wrap">
375 <h1><?php esc_html_e( 'WP Debugging', 'wp-debugging' ); ?></h1>
376 <div class="updated fade">
377 <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>
378 </div>
379 <div>
380 <form method="post" action="<?php esc_attr_e( $action ); ?>">
381 <?php settings_fields( 'wp_debugging' ); ?>
382 <?php do_settings_sections( 'wp_debugging' ); ?>
383 <?php submit_button(); ?>
384 </form>
385 </div>
386 <?php
387 }
388
389 /**
390 * Sanitize save settings.
391 *
392 * @param array $input Input.
393 * @return array $new_input Sanitized output.
394 */
395 public function sanitize( $input ) {
396 $new_input = [];
397 if ( ! is_array( $input ) ) {
398 $new_input = sanitize_text_field( $input );
399 } else {
400 foreach ( array_keys( (array) $input ) as $id ) {
401 $new_input[ sanitize_text_field( $id ) ] = sanitize_text_field( $input[ $id ] );
402 }
403 }
404
405 return $new_input;
406 }
407
408 /**
409 * Get the settings option array and print one of its values.
410 *
411 * @param array $args 'id' and 'title'.
412 */
413 public function checkbox_setting( $args ) {
414 $checked = isset( self::$options[ $args['id'] ] ) ? self::$options[ $args['id'] ] : null;
415 ?>
416 <style> .form-table th { display:none; } </style>
417 <label for="<?php esc_attr_e( $args['id'] ); ?>">
418 <input type="checkbox" name="wp-debugging[<?php esc_attr_e( $args['id'] ); ?>]" value="1" <?php checked( '1', $checked ); ?> >
419 <?php esc_html_e( $args['title'] ); ?>
420 </label>
421 <?php
422 }
423
424 /**
425 * Add setting link to plugin page.
426 * Applied to the list of links to display on the plugins page (beside the activate/deactivate links).
427 *
428 * @param array $links Plugin links on plugins.php.
429 *
430 * @return array
431 */
432 public function plugin_action_links( $links ) {
433 $settings_page = is_multisite() ? 'settings.php' : 'tools.php';
434 $link = [ '<a href="' . esc_url( network_admin_url( $settings_page ) ) . '?page=wp-debugging">' . esc_html__( 'Settings', 'wp-debugging' ) . '</a>' ];
435
436 return array_merge( $links, $link );
437 }
438 }
439