PluginProbe
WP Debugging / trunk
WP Debugging vtrunk
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 / Bootstrap.php

Bootstrap.php in WP Debugging trunk, at src/Bootstrap.php

224 lines 5.9 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 // Exit if called directly.
13 if ( ! defined( 'WPINC' ) ) {
14 die;
15 }
16
17 /**
18 * Class Bootstrap
19 */
20 class Bootstrap {
21 /**
22 * Holds main plugin file.
23 *
24 * @var string
25 */
26 protected $file;
27
28 /**
29 * Holds main plugin directory.
30 *
31 * @var string
32 */
33 protected $dir;
34
35 /**
36 * Holds plugin options.
37 *
38 * @var array
39 */
40 protected static $options;
41
42 /**
43 * Holds `wp-config.php` file path.
44 *
45 * @var string
46 */
47 protected static $config_path;
48
49 /**
50 * Holds pre-defined constants for `wp-config.php`.
51 *
52 * @var array
53 */
54 protected $defined_constants = [ 'wp_debug_log', 'script_debug', 'savequeries', 'wp_debug', 'wp_debug_display', 'wp_disable_fatal_error_handler' ];
55
56 /**
57 * Constructor.
58 *
59 * @param string $file Main plugin file.
60 * @return void
61 */
62 public function __construct( $file ) {
63 $this->file = $file;
64 $this->dir = dirname( $file );
65 self::$options = get_site_option( 'wp_debugging', [ 'wp_debug' => '1' ] );
66 self::$config_path = $this->get_config_path();
67 @ini_set( 'display_errors', 1 ); // phpcs:ignore WordPress.PHP.IniSet.display_errors_Blacklisted,WordPress.PHP.NoSilencedErrors.Discouraged,WordPress.PHP.IniSet.display_errors_Disallowed
68 }
69
70 /**
71 * Test for writable wp-config.php, exit with notice if not available.
72 *
73 * @return bool|void
74 */
75 public function init() {
76 register_activation_hook( $this->file, [ $this, 'activate' ] );
77 register_deactivation_hook( $this->file, [ $this, 'deactivate' ] );
78
79 // Load settings hooks and exit if not on WP Debugging settings page.
80 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
81 if ( ! isset( $_REQUEST['page'] ) || 'wp-debugging' !== sanitize_key( wp_unslash( $_REQUEST['page'] ) ) ) {
82 ( new Settings( self::$options, self::$config_path, $this->defined_constants ) )
83 ->load_hooks();
84 return;
85 }
86
87 if ( ! is_writable( self::$config_path ) ) {
88 echo '<div class="error notice is-dismissible"><p>';
89 echo wp_kses_post( __( 'The <strong>WP Debugging</strong> plugin must have a <code>wp-config.php</code> file that is writable by the filesystem.', 'wp-debugging' ) );
90 echo '</p></div>';
91
92 return false;
93 }
94
95 $this->load_hooks();
96 }
97
98 /**
99 * Get the `wp-config.php` file path.
100 *
101 * The config file may reside one level above ABSPATH but is not part of another installation.
102 *
103 * @see wp-load.php#L26-L42
104 *
105 * @return string $config_path
106 */
107 public function get_config_path() {
108 $config_path = ABSPATH . 'wp-config.php';
109
110 if ( ! file_exists( $config_path ) ) {
111 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
112 if ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
113 $config_path = dirname( ABSPATH ) . '/wp-config.php';
114 }
115 }
116
117 /**
118 * Filter the config file path.
119 *
120 * @since 2.3.0
121 *
122 * @param string $config_path
123 */
124 return apply_filters( 'wp_debugging_config_path', $config_path );
125 }
126
127 /**
128 * Load hooks.
129 *
130 * @return void
131 */
132 public function load_hooks() {
133 add_action(
134 'plugins_loaded',
135 function () {
136 ( new Settings( self::$options, self::$config_path, $this->defined_constants ) )
137 ->load_hooks()
138 ->process_filter_constants();
139 }
140 );
141 add_filter(
142 'wp_dependency_timeout',
143 function ( $timeout, $source ) {
144 $timeout = basename( $this->dir ) !== $source ? $timeout : 45;
145
146 return $timeout;
147 },
148 10,
149 2
150 );
151 add_action(
152 'plugins_loaded',
153 function () {
154 \WP_Dependency_Installer::instance()->run( $this->dir );
155 }
156 );
157 }
158
159 /**
160 * Run on activation.
161 * Reloads constants to wp-config.php, including saved options.
162 *
163 * @return void
164 */
165 public function activate() {
166 $this->set_pre_activation_constants();
167
168 // Need to remove user defined constants from filter.
169 $user_defined = apply_filters( 'wp_debugging_add_constants', [] );
170 foreach ( array_keys( $user_defined ) as $defined ) {
171 unset( self::$options[ $defined ] );
172 }
173
174 $constants = [ 'wp_debug_log', 'script_debug', 'savequeries' ];
175 $constants = array_flip( array_merge( array_keys( self::$options ), $constants ) );
176
177 ( new Settings( self::$options, self::$config_path, $this->defined_constants ) )->add_constants( $constants );
178 }
179
180 /**
181 * Run on deactivation.
182 * Removes all added constants from wp-config.php.
183 *
184 * @return void
185 */
186 public function deactivate() {
187 $restore_constants = get_site_option( 'wp_debugging_restore' );
188 $remove_user_added = array_diff( self::$options, array_flip( $this->defined_constants ) );
189 $remove_constants = array_diff( array_flip( $this->defined_constants ), array_keys( (array) $restore_constants ) );
190 $remove_constants = array_merge( $remove_constants, $remove_user_added );
191
192 ( new Settings( self::$options, self::$config_path, $this->defined_constants ) )->remove_constants( $remove_constants );
193
194 $this->restore_pre_activation_constants();
195 }
196
197 /**
198 * Set pre-activation constant from `wp-config.php`.
199 *
200 * @return void
201 */
202 private function set_pre_activation_constants() {
203 $config_transformer = new \WPConfigTransformer( self::$config_path );
204 $predefined_constants = [];
205 foreach ( $this->defined_constants as $defined_constant ) {
206 if ( $config_transformer->exists( 'constant', strtoupper( $defined_constant ) ) ) {
207 $value = $config_transformer->get_value( 'constant', strtoupper( $defined_constant ) );
208 $predefined_constants[ $defined_constant ]['value'] = $value;
209 }
210 }
211 update_site_option( 'wp_debugging_restore', $predefined_constants );
212 }
213
214 /**
215 * Restore pre-activation constants to `wp-config.php`.
216 *
217 * @return void
218 */
219 private function restore_pre_activation_constants() {
220 $restore_constants = get_site_option( 'wp_debugging_restore' );
221 ( new Settings( self::$options, self::$config_path, $this->defined_constants ) )->add_constants( $restore_constants );
222 }
223 }
224