PluginProbe
Debug Log Manager – Conveniently Monitor and Inspect Errors / 1.3.3
Debug Log Manager – Conveniently Monitor and Inspect Errors v1.3.3
2.5.2 2.5.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.3.0 1.3.1 1.3.3 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.8.0 1.8.2 1.8.3 1.8.4 All 49 releases
debug-log-manager / classes / class-wp-config-transformer.php

class-wp-config-transformer.php in Debug Log Manager – Conveniently Monitor and Inspect Errors 1.3.3, at classes/class-wp-config-transformer.php

390 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace DLM\Classes;
4
5 use Exception;
6
7 /**
8 * Class with methods to manipulate wp-config.php
9 *
10 * @since 1.0.0
11 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
12 */
13 class WP_Config_Transformer {
14
15 /**
16 * The wp-config.php source file
17 *
18 * @since 1.0.0
19 * @access private
20 * @var string $version The current version of this plugin.
21 */
22 private $wp_config_src;
23
24 /**
25 * The configs defined in wp-config.php
26 *
27 * @since 1.0.0
28 * @access private
29 * @var string $version The current version of this plugin.
30 */
31 private $wp_configs;
32
33 /**
34 * Get wp-config.php file path
35 *
36 * @since 1.0.0
37 */
38 public function wpconfig_file_path() {
39
40 $file = ABSPATH . 'wp-config.php';
41 if ( ! file_exists( $file ) ) {
42 if ( file_exists( dirname( ABSPATH ) . '/wp-config.php') ) {
43 $file = dirname( ABSPATH ) . '/wp-config.php'; // wp-config.php file is in the folder above the WP root folder
44 }
45 }
46
47 return $file;
48
49 }
50
51 /**
52 * Get configs in wp-config.php
53 *
54 * @since 1.0.0
55 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
56 */
57 public function configs( $return_type = 'raw' ) {
58
59 $src = file_get_contents( $this->wpconfig_file_path() );
60
61 $configs = array();
62 $configs['constant'] = array();
63 $configs['variable'] = array();
64
65 // Strip comments.
66 foreach ( token_get_all( $src ) as $token ) {
67 if ( in_array( $token[0], array( T_COMMENT, T_DOC_COMMENT ), true ) ) {
68 $src = str_replace( $token[1], '', $src );
69 }
70 }
71
72 preg_match_all( '/(?<=^|;|<\?php\s|<\?\s)(\h*define\s*\(\s*[\'"](\w*?)[\'"]\s*)(,\s*(\'\'|""|\'.*?[^\\\\]\'|".*?[^\\\\]"|.*?)\s*)((?:,\s*(?:true|false)\s*)?\)\s*;)/ims', $src, $constants );
73 preg_match_all( '/(?<=^|;|<\?php\s|<\?\s)(\h*\$(\w+)\s*=)(\s*(\'\'|""|\'.*?[^\\\\]\'|".*?[^\\\\]"|.*?)\s*;)/ims', $src, $variables );
74
75 if ( ! empty( $constants[0] ) && ! empty( $constants[1] ) && ! empty( $constants[2] ) && ! empty( $constants[3] ) && ! empty( $constants[4] ) && ! empty( $constants[5] ) ) {
76 foreach ( $constants[2] as $index => $name ) {
77 $configs['constant'][ $name ] = array(
78 'src' => $constants[0][ $index ],
79 'value' => $constants[4][ $index ],
80 'parts' => array(
81 $constants[1][ $index ],
82 $constants[3][ $index ],
83 $constants[5][ $index ],
84 ),
85 );
86 }
87 }
88
89 if ( ! empty( $variables[0] ) && ! empty( $variables[1] ) && ! empty( $variables[2] ) && ! empty( $variables[3] ) && ! empty( $variables[4] ) ) {
90 // Remove duplicate(s), last definition wins.
91 $variables[2] = array_reverse( array_unique( array_reverse( $variables[2], true ) ), true );
92 foreach ( $variables[2] as $index => $name ) {
93 $configs['variable'][ $name ] = array(
94 'src' => $variables[0][ $index ],
95 'value' => $variables[4][ $index ],
96 'parts' => array(
97 $variables[1][ $index ],
98 $variables[3][ $index ],
99 ),
100 );
101 }
102 }
103
104 $this->wp_configs = $configs;
105
106 if ( $return_type == 'raw' ) {
107 return $configs;
108 } elseif ( $return_type == 'print_r' ) {
109 return '<pre>' . print_r( $configs, true ) . '</pre>';
110 }
111 }
112
113 /**
114 * Checks if a config exists in the wp-config.php file.
115 *
116 * @throws Exception If the wp-config.php file is empty.
117 * @throws Exception If the requested config type is invalid.
118 *
119 * @param string $type Config type (constant or variable).
120 * @param string $name Config name.
121 *
122 * @return bool
123 * @since 1.0.0
124 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
125 */
126 public function exists( $type, $name ) {
127 $wp_config_src = file_get_contents( $this->wpconfig_file_path() );
128
129 if ( ! trim( $wp_config_src ) ) {
130 throw new Exception( 'Config file is empty.' );
131 }
132 // Normalize the newline to prevent an issue coming from OSX.
133 $this->wp_config_src = str_replace( array( "\n\r", "\r" ), "\n", $wp_config_src );
134
135 $this->wp_configs = $this->configs( 'raw' );
136
137 if ( ! isset( $this->wp_configs[ $type ] ) ) {
138 throw new Exception( "Config type '{$type}' does not exist." );
139 }
140
141 return isset( $this->wp_configs[ $type ][ $name ] );
142 }
143
144 /**
145 * Get the value of a config in the wp-config.php file.
146 *
147 * @throws Exception If the wp-config.php file is empty.
148 * @throws Exception If the requested config type is invalid.
149 *
150 * @param string $type Config type (constant or variable).
151 * @param string $name Config name.
152 *
153 * @return array
154 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
155 */
156 public function get_value( $type, $name ) {
157 $wp_config_src = file_get_contents( $this->wpconfig_file_path() );
158
159 if ( ! trim( $wp_config_src ) ) {
160 throw new Exception( 'Config file is empty.' );
161 }
162
163 $this->wp_config_src = $wp_config_src;
164 $this->wp_configs = $this->configs( 'raw' );
165
166 if ( ! isset( $this->wp_configs[ $type ] ) ) {
167 throw new Exception( "Config type '{$type}' does not exist." );
168 }
169
170 return $this->wp_configs[ $type ][ $name ]['value'];
171 }
172
173 /**
174 * Adds a config to the wp-config.php file.
175 *
176 * @throws Exception If the config value provided is not a string.
177 * @throws Exception If the config placement anchor could not be located.
178 *
179 * @param string $type Config type (constant or variable).
180 * @param string $name Config name.
181 * @param string $value Config value.
182 * @param array $options (optional) Array of special behavior options.
183 *
184 * @return bool
185 * @since 1.0.0
186 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
187 */
188 public function add( $type, $name, $value, array $options = array() ) {
189 if ( ! is_string( $value ) ) {
190 throw new Exception( 'Config value must be a string.' );
191 }
192
193 if ( $this->exists( $type, $name ) ) {
194 return false;
195 }
196
197 if ( in_array( $value, array( 'true', 'false' ), true ) ) {
198 $raw_input = true;
199 } else {
200 $raw_input = false;
201 }
202
203 $defaults = array(
204 'raw' => $raw_input, // Display value in raw format without quotes.
205 'anchor' => "/* That's all, stop editing! Happy publishing. */", // Config placement anchor string.
206 'separator' => PHP_EOL, // Separator between config definition and anchor string.
207 'placement' => 'before', // Config placement direction (insert before or after).
208 );
209
210 // list( $raw, $anchor, $separator, $placement ) = array_values( $options );
211 list( $raw, $anchor, $separator, $placement ) = array_values( array_merge( $defaults, $options ) );;
212
213 $raw = (bool) $raw;
214 $anchor = (string) $anchor;
215 $separator = (string) $separator;
216 $placement = (string) $placement;
217
218 if ( 'EOF' === $anchor ) {
219 $contents = $this->wp_config_src . $this->normalize( $type, $name, $this->format_value( $value, $raw ) );
220 } else {
221 if ( false === strpos( $this->wp_config_src, $anchor ) ) {
222 throw new Exception( 'Unable to locate placement anchor.' );
223 }
224
225 $new_src = $this->normalize( $type, $name, $this->format_value( $value, $raw ) );
226 $new_src = ( 'after' === $placement ) ? $anchor . $separator . $new_src : $new_src . $separator . $anchor;
227 $contents = str_replace( $anchor, $new_src, $this->wp_config_src );
228 }
229
230 return $this->save( $contents );
231 }
232
233 /**
234 * Updates an existing config in the wp-config.php file.
235 *
236 * @throws Exception If the config value provided is not a string.
237 *
238 * @param string $type Config type (constant or variable).
239 * @param string $name Config name.
240 * @param string $value Config value.
241 * @param array $options (optional) Array of special behavior options.
242 *
243 * @return bool
244 * @since 1.0.0
245 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
246 */
247 public function update( $type, $name, $value, array $options = array() ) {
248 if ( ! is_string( $value ) ) {
249 throw new Exception( 'Config value must be a string.' );
250 }
251
252 // $defaults = array(
253 // 'add' => true, // Add the config if missing.
254 // 'raw' => false, // Display value in raw format without quotes.
255 // 'normalize' => false, // Normalize config output using WP Coding Standards.
256 // );
257
258 // list( $add, $raw, $normalize ) = array_values( array_merge( $defaults, $options ) );
259 list( $add, $raw, $normalize ) = array_values( $options );
260
261 $add = (bool) $add;
262 $raw = (bool) $raw;
263 $normalize = (bool) $normalize;
264
265 if ( ! $this->exists( $type, $name ) ) {
266 return ( $add ) ? $this->add( $type, $name, $value ) : false;
267 }
268
269 $old_src = $this->wp_configs[ $type ][ $name ]['src'];
270 $old_value = $this->wp_configs[ $type ][ $name ]['value'];
271 $new_value = $this->format_value( $value, $raw );
272
273 if ( $normalize ) {
274 $new_src = $this->normalize( $type, $name, $new_value );
275 } else {
276 $new_parts = $this->wp_configs[ $type ][ $name ]['parts'];
277 $new_parts[1] = str_replace( $old_value, $new_value, $new_parts[1] ); // Only edit the value part.
278 $new_src = implode( '', $new_parts );
279 }
280
281 $contents = preg_replace(
282 sprintf( '/(?<=^|;|<\?php\s|<\?\s)(\s*?)%s/m', preg_quote( trim( $old_src ), '/' ) ),
283 '$1' . str_replace( '$', '\$', trim( $new_src ) ),
284 $this->wp_config_src
285 );
286
287 return $this->save( $contents );
288 }
289
290 /**
291 * Removes a config from the wp-config.php file.
292 *
293 * @param string $type Config type (constant or variable).
294 * @param string $name Config name.
295 *
296 * @return bool
297 * @since 1.0.0
298 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
299 */
300 public function remove( $type, $name ) {
301 if ( ! $this->exists( $type, $name ) ) {
302 return false;
303 }
304
305 $wp_config_src = file_get_contents( $this->wpconfig_file_path() );
306 $this->wp_config_src = str_replace( array( "\n\r", "\r" ), "\n", $wp_config_src );
307 $this->wp_configs = $this->configs( 'raw' );
308
309 $pattern = sprintf( '/(?<=^|;|<\?php\s|<\?\s)%s\s*(\S|$)/m', preg_quote( $this->wp_configs[$type][$name]['src'], '/' ) );
310 $contents = preg_replace( $pattern, '$1', $this->wp_config_src );
311
312 return $this->save( $contents );
313 }
314
315 /**
316 * Applies formatting to a config value.
317 *
318 * @throws Exception When a raw value is requested for an empty string.
319 *
320 * @param string $value Config value.
321 * @param bool $raw Display value in raw format without quotes.
322 *
323 * @return mixed
324 * @since 1.0.0
325 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
326 */
327 public function format_value( $value, $raw ) {
328 if ( $raw && '' === trim( $value ) ) {
329 throw new Exception( 'Raw value for empty string not supported.' );
330 }
331
332 return ( $raw ) ? $value : var_export( $value, true );
333 }
334
335 /**
336 * Normalizes the source output for a name/value pair.
337 *
338 * @throws Exception If the requested config type does not support normalization.
339 *
340 * @param string $type Config type (constant or variable).
341 * @param string $name Config name.
342 * @param mixed $value Config value.
343 *
344 * @return string
345 * @since 1.0.0
346 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
347 */
348 public function normalize( $type, $name, $value ) {
349 if ( 'constant' === $type ) {
350 $placeholder = "define( '%s', %s );";
351 } elseif ( 'variable' === $type ) {
352 $placeholder = '$%s = %s;';
353 } else {
354 throw new Exception( "Unable to normalize config type '{$type}'." );
355 }
356
357 return sprintf( $placeholder, $name, $value );
358 }
359
360 /**
361 * Saves new contents to the wp-config.php file.
362 *
363 * @throws Exception If the config file content provided is empty.
364 * @throws Exception If there is a failure when saving the wp-config.php file.
365 *
366 * @param string $contents New config contents.
367 *
368 * @return bool
369 * @since 1.0.0
370 * @link https://plugins.svn.wordpress.org/debug-log-config-tool/tags/1.1/src/Classes/vendor/WPConfigTransformer.php
371 */
372 public function save( $contents ) {
373 if ( ! trim( $contents ) ) {
374 throw new Exception( 'Cannot save the config file with empty contents.' );
375 }
376
377 if ( $contents === $this->wp_config_src ) {
378 return false;
379 }
380
381 $result = file_put_contents( $this->wpconfig_file_path(), $contents, LOCK_EX );
382
383 if ( false === $result ) {
384 throw new Exception( 'Failed to update the config file.' );
385 }
386
387 return true;
388 }
389
390 }