| 1 | <?php |
| 2 | /** |
| 3 | * Get system status for debugging and support. |
| 4 | * |
| 5 | * @package WordPress |
| 6 | * @subpackage Administration |
| 7 | */ |
| 8 | |
| 9 | /** WordPress Administration Bootstrap */ |
| 10 | require_once dirname( __FILE__ ) . '/admin.php'; |
| 11 | |
| 12 | if ( ! current_user_can( 'update_core' ) ) { |
| 13 | wp_die( __( 'Sorry, you do not have permission to access this page.' ) ); |
| 14 | } |
| 15 | |
| 16 | global $wpdb; |
| 17 | |
| 18 | $title = __( 'System information' ); |
| 19 | |
| 20 | require_once ABSPATH . 'wp-admin/admin-header.php'; |
| 21 | ?> |
| 22 | |
| 23 | <div class="wrap"> |
| 24 | <h1 class="wp-heading-inline"> |
| 25 | <?php echo esc_html( $title ); ?> |
| 26 | |
| 27 | <?php if ( function_exists( 'phpinfo' ) ) { ?> |
| 28 | <?php if ( ! isset( $_GET['phpinfo'] ) ) { ?> |
| 29 | <a href="<?php echo esc_url( admin_url( 'info.php?phpinfo' ) ); ?>" class="page-title-action"><?php esc_html_e( 'PHP Information' ); ?></a> |
| 30 | <?php } else { ?> |
| 31 | <a href="<?php echo esc_url( admin_url( 'info.php' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Debug Information' ); ?></a> |
| 32 | <?php } ?> |
| 33 | <?php } ?> |
| 34 | </h1> |
| 35 | |
| 36 | <hr class="wp-header-end"> |
| 37 | |
| 38 | <?php |
| 39 | if ( ! isset( $_GET['phpinfo'] ) ) { |
| 40 | |
| 41 | // Trigger all update checks |
| 42 | wp_version_check(); |
| 43 | wp_update_plugins(); |
| 44 | wp_update_themes(); |
| 45 | |
| 46 | global $wpdb; |
| 47 | |
| 48 | $upload_dir = wp_upload_dir(); |
| 49 | if ( file_exists( ABSPATH . 'wp-config.php' ) ) { |
| 50 | $wp_config_path = ABSPATH . 'wp-config.php'; |
| 51 | } elseif ( file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) { |
| 52 | $wp_config_path = dirname( ABSPATH ) . '/wp-config.php'; |
| 53 | } |
| 54 | |
| 55 | $core_current_version = get_bloginfo( 'version' ); |
| 56 | $core_updates = get_core_updates(); |
| 57 | |
| 58 | foreach ( $core_updates as $core => $update ) { |
| 59 | if ( 'upgrade' === $update->response ) { |
| 60 | // translators: %s: Latest WordPress version number. |
| 61 | $core_update_needed = ' ' . sprintf( __( '( Latest version: %s )' ), $update->version ); |
| 62 | } else { |
| 63 | $core_update_needed = ''; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | $info = array( |
| 68 | 'wp-core' => array( |
| 69 | 'label' => __( 'WordPress' ), |
| 70 | 'fields' => array( |
| 71 | array( |
| 72 | 'label' => __( 'Version' ), |
| 73 | 'value' => $core_current_version . $core_update_needed, |
| 74 | ), |
| 75 | array( |
| 76 | 'label' => __( 'Site Language' ), |
| 77 | 'value' => get_locale(), |
| 78 | ), |
| 79 | array( |
| 80 | 'label' => __( 'Home URL' ), |
| 81 | 'value' => get_bloginfo( 'url' ), |
| 82 | 'private' => true, |
| 83 | ), |
| 84 | array( |
| 85 | 'label' => __( 'Site URL' ), |
| 86 | 'value' => get_bloginfo( 'wpurl' ), |
| 87 | 'private' => true, |
| 88 | ), |
| 89 | array( |
| 90 | 'label' => __( 'Permalink structure' ), |
| 91 | 'value' => get_option( 'permalink_structure' ), |
| 92 | ), |
| 93 | array( |
| 94 | 'label' => __( 'Is this site using HTTPS?' ), |
| 95 | 'value' => ( is_ssl() ? __( 'Yes' ) : __( 'No' ) ), |
| 96 | ), |
| 97 | array( |
| 98 | 'label' => __( 'Can anyone register on this site?' ), |
| 99 | 'value' => ( get_option( 'users_can_register' ) ? __( 'Yes' ) : __( 'No' ) ), |
| 100 | ), |
| 101 | array( |
| 102 | 'label' => __( 'Default comment status' ), |
| 103 | 'value' => get_option( 'default_comment_status' ), |
| 104 | ), |
| 105 | array( |
| 106 | 'label' => __( 'Is this a multisite?' ), |
| 107 | 'value' => ( is_multisite() ? __( 'Yes' ) : __( 'No' ) ), |
| 108 | ), |
| 109 | ), |
| 110 | ), |
| 111 | 'wp-dropins' => array( |
| 112 | 'label' => __( 'Drop-ins' ), |
| 113 | 'description' => __( 'Drop-ins are single files that replace or enhance WordPress features in ways that are not possible for traditional plugins' ), |
| 114 | 'fields' => array(), |
| 115 | ), |
| 116 | 'wp-active-theme' => array( |
| 117 | 'label' => __( 'Active Theme' ), |
| 118 | 'fields' => array(), |
| 119 | ), |
| 120 | 'wp-themes' => array( |
| 121 | 'label' => __( 'Other themes' ), |
| 122 | 'show_count' => true, |
| 123 | 'fields' => array(), |
| 124 | ), |
| 125 | 'wp-mu-plugins' => array( |
| 126 | 'label' => __( 'Must Use Plugins' ), |
| 127 | 'show_count' => true, |
| 128 | 'fields' => array(), |
| 129 | ), |
| 130 | 'wp-plugins-active' => array( |
| 131 | 'label' => __( 'Active Plugins' ), |
| 132 | 'show_count' => true, |
| 133 | 'fields' => array(), |
| 134 | ), |
| 135 | 'wp-plugins-inactive' => array( |
| 136 | 'label' => __( 'Inactive Plugins' ), |
| 137 | 'show_count' => true, |
| 138 | 'fields' => array(), |
| 139 | ), |
| 140 | 'wp-media' => array( |
| 141 | 'label' => __( 'Media handling' ), |
| 142 | 'fields' => array(), |
| 143 | ), |
| 144 | 'wp-server' => array( |
| 145 | 'label' => __( 'Server' ), |
| 146 | 'description' => __( 'The options shown below relate to your server setup. If changes are required, you may need your web host\'s assistance.' ), |
| 147 | 'fields' => array(), |
| 148 | ), |
| 149 | 'wp-database' => array( |
| 150 | 'label' => __( 'Database' ), |
| 151 | 'fields' => array(), |
| 152 | ), |
| 153 | 'wp-constants' => array( |
| 154 | 'label' => __( 'WordPress constants' ), |
| 155 | 'description' => __( 'These values represent values set in your websites code which affect WordPress in various ways that may be of importance when seeking help with your site.' ), |
| 156 | 'fields' => array( |
| 157 | array( |
| 158 | 'label' => 'ABSPATH', |
| 159 | 'value' => ( ! defined( 'ABSPATH' ) ? __( 'Undefined' ) : ABSPATH ), |
| 160 | ), |
| 161 | array( |
| 162 | 'label' => 'WP_HOME', |
| 163 | 'value' => ( ! defined( 'WP_HOME' ) ? __( 'Undefined' ) : WP_HOME ), |
| 164 | ), |
| 165 | array( |
| 166 | 'label' => 'WP_SITEURL', |
| 167 | 'value' => ( ! defined( 'WP_SITEURL' ) ? __( 'Undefined' ) : WP_SITEURL ), |
| 168 | ), |
| 169 | array( |
| 170 | 'label' => 'WP_DEBUG', |
| 171 | 'value' => ( ! defined( 'WP_DEBUG' ) ? __( 'Undefined' ) : ( WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 172 | ), |
| 173 | array( |
| 174 | 'label' => 'WP_MAX_MEMORY_LIMIT', |
| 175 | 'value' => ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ? __( 'Undefined' ) : WP_MAX_MEMORY_LIMIT ), |
| 176 | ), |
| 177 | array( |
| 178 | 'label' => 'WP_DEBUG_DISPLAY', |
| 179 | 'value' => ( ! defined( 'WP_DEBUG_DISPLAY' ) ? __( 'Undefined' ) : ( WP_DEBUG_DISPLAY ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 180 | ), |
| 181 | array( |
| 182 | 'label' => 'WP_DEBUG_LOG', |
| 183 | 'value' => ( ! defined( 'WP_DEBUG_LOG' ) ? __( 'Undefined' ) : ( WP_DEBUG_LOG ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 184 | ), |
| 185 | array( |
| 186 | 'label' => 'SCRIPT_DEBUG', |
| 187 | 'value' => ( ! defined( 'SCRIPT_DEBUG' ) ? __( 'Undefined' ) : ( SCRIPT_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 188 | ), |
| 189 | array( |
| 190 | 'label' => 'WP_CACHE', |
| 191 | 'value' => ( ! defined( 'WP_CACHE' ) ? __( 'Undefined' ) : ( WP_CACHE ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 192 | ), |
| 193 | array( |
| 194 | 'label' => 'CONCATENATE_SCRIPTS', |
| 195 | 'value' => ( ! defined( 'CONCATENATE_SCRIPTS' ) ? __( 'Undefined' ) : ( CONCATENATE_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 196 | ), |
| 197 | array( |
| 198 | 'label' => 'COMPRESS_SCRIPTS', |
| 199 | 'value' => ( ! defined( 'COMPRESS_SCRIPTS' ) ? __( 'Undefined' ) : ( COMPRESS_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 200 | ), |
| 201 | array( |
| 202 | 'label' => 'COMPRESS_CSS', |
| 203 | 'value' => ( ! defined( 'COMPRESS_CSS' ) ? __( 'Undefined' ) : ( COMPRESS_CSS ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 204 | ), |
| 205 | array( |
| 206 | 'label' => 'WP_LOCAL_DEV', |
| 207 | 'value' => ( ! defined( 'WP_LOCAL_DEV' ) ? __( 'Undefined' ) : ( WP_LOCAL_DEV ? __( 'Enabled' ) : __( 'Disabled' ) ) ), |
| 208 | ), |
| 209 | ), |
| 210 | ), |
| 211 | 'wp-filesystem' => array( |
| 212 | 'label' => __( 'Filesystem permissions' ), |
| 213 | 'description' => __( 'The status of various locations WordPress needs to write files in various scenarios.' ), |
| 214 | 'fields' => array( |
| 215 | array( |
| 216 | 'label' => __( 'The main WordPress directory' ), |
| 217 | 'value' => ( wp_is_writable( ABSPATH ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 218 | ), |
| 219 | array( |
| 220 | 'label' => __( 'The wp-content directory' ), |
| 221 | 'value' => ( wp_is_writable( WP_CONTENT_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 222 | ), |
| 223 | array( |
| 224 | 'label' => __( 'The uploads directory' ), |
| 225 | 'value' => ( wp_is_writable( $upload_dir['basedir'] ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 226 | ), |
| 227 | array( |
| 228 | 'label' => __( 'The plugins directory' ), |
| 229 | 'value' => ( wp_is_writable( WP_PLUGIN_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 230 | ), |
| 231 | array( |
| 232 | 'label' => __( 'The themes directory' ), |
| 233 | 'value' => ( wp_is_writable( get_template_directory() . '/..' ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 234 | ), |
| 235 | ), |
| 236 | ), |
| 237 | ); |
| 238 | |
| 239 | if ( is_multisite() ) { |
| 240 | $network_query = new WP_Network_Query(); |
| 241 | $network_ids = $network_query->query( array( |
| 242 | 'fields' => 'ids', |
| 243 | 'number' => 100, |
| 244 | 'no_found_rows' => false, |
| 245 | ) ); |
| 246 | |
| 247 | $site_count = 0; |
| 248 | foreach ( $network_ids as $network_id ) { |
| 249 | $site_count += get_blog_count( $network_id ); |
| 250 | } |
| 251 | |
| 252 | $info['wp-core']['fields'][] = array( |
| 253 | 'label' => __( 'User Count' ), |
| 254 | 'value' => get_user_count(), |
| 255 | ); |
| 256 | $info['wp-core']['fields'][] = array( |
| 257 | 'label' => __( 'Site Count' ), |
| 258 | 'value' => $site_count, |
| 259 | ); |
| 260 | $info['wp-core']['fields'][] = array( |
| 261 | 'label' => __( 'Network Count' ), |
| 262 | 'value' => $network_query->found_networks, |
| 263 | ); |
| 264 | } else { |
| 265 | $user_count = count_users(); |
| 266 | |
| 267 | $info['wp-core']['fields'][] = array( |
| 268 | 'label' => __( 'User Count' ), |
| 269 | 'value' => $user_count['total_users'], |
| 270 | ); |
| 271 | } |
| 272 | |
| 273 | // WordPress features requiring processing. |
| 274 | $wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) ); |
| 275 | if ( ! is_wp_error( $wp_dotorg ) ) { |
| 276 | $info['wp-core']['fields'][] = array( |
| 277 | 'label' => __( 'Communication with WordPress.org' ), |
| 278 | 'value' => sprintf( |
| 279 | __( 'WordPress.org is reachable' ) |
| 280 | ), |
| 281 | ); |
| 282 | } else { |
| 283 | $info['wp-core']['fields'][] = array( |
| 284 | 'label' => __( 'Communication with WordPress.org' ), |
| 285 | 'value' => sprintf( |
| 286 | // translators: %1$s: The IP address WordPress.org resolves to. %2$s: The error returned by the lookup. |
| 287 | __( 'Unable to reach WordPress.org at %1$s: %2$s' ), |
| 288 | gethostbyname( 'wordpress.org' ), |
| 289 | $wp_dotorg->get_error_message() |
| 290 | ), |
| 291 | ); |
| 292 | } |
| 293 | |
| 294 | // Get drop-ins. |
| 295 | $dropins = get_dropins(); |
| 296 | $dropin_description = _get_dropins(); |
| 297 | foreach ( $dropins as $dropin_key => $dropin ) { |
| 298 | $info['wp-dropins']['fields'][] = array( |
| 299 | 'label' => $dropin_key, |
| 300 | 'value' => $dropin_description[ $dropin_key ][0], |
| 301 | ); |
| 302 | } |
| 303 | |
| 304 | // Populate the media fields. |
| 305 | $info['wp-media']['fields'][] = array( |
| 306 | 'label' => __( 'Active editor' ), |
| 307 | 'value' => _wp_image_editor_choose(), |
| 308 | ); |
| 309 | |
| 310 | // Get ImageMagic information, if available. |
| 311 | if ( class_exists( 'Imagick' ) ) { |
| 312 | // Save the Imagick instance for later use. |
| 313 | $imagick = new Imagick(); |
| 314 | $imagick_version = $imagick->getVersion(); |
| 315 | } else { |
| 316 | $imagick_version = 'Imagick not available'; |
| 317 | } |
| 318 | $info['wp-media']['fields'][] = array( |
| 319 | 'label' => __( 'Imagick Module Version' ), |
| 320 | 'value' => ( is_array( $imagick_version ) ? $imagick_version['versionNumber'] : $imagick_version ), |
| 321 | ); |
| 322 | $info['wp-media']['fields'][] = array( |
| 323 | 'label' => __( 'ImageMagick Version' ), |
| 324 | 'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ), |
| 325 | ); |
| 326 | |
| 327 | // If Imagick is used as our editor, provide some more information about its limitations. |
| 328 | if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) { |
| 329 | $limits = array( |
| 330 | array( |
| 331 | 'label' => __( 'Area' ), |
| 332 | 'value' => defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : __( 'Not Available' ), |
| 333 | ), |
| 334 | array( |
| 335 | 'label' => __( 'Disk' ), |
| 336 | 'value' => defined( 'imagick::RESOURCETYPE_DISK' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_DISK ) : __( 'Not Available' ), |
| 337 | ), |
| 338 | array( |
| 339 | 'label' => __( 'File' ), |
| 340 | 'value' => defined( 'imagick::RESOURCETYPE_FILE' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_FILE ) : __( 'Not Available' ), |
| 341 | ), |
| 342 | array( |
| 343 | 'label' => __( 'Map' ), |
| 344 | 'value' => defined( 'imagick::RESOURCETYPE_MAP' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MAP ) ) : __( 'Not Available' ), |
| 345 | ), |
| 346 | array( |
| 347 | 'label' => __( 'Memory' ), |
| 348 | 'value' => defined( 'imagick::RESOURCETYPE_MEMORY' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MEMORY ) ) : __( 'Not Available' ), |
| 349 | ), |
| 350 | array( |
| 351 | 'label' => __( 'Thread' ), |
| 352 | 'value' => defined( 'imagick::RESOURCETYPE_THREAD' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_THREAD ) : __( 'Not Available' ), |
| 353 | ), |
| 354 | ); |
| 355 | |
| 356 | $info['wp-media']['fields'][] = array( |
| 357 | 'label' => __( 'Imagick Resource Limits' ), |
| 358 | 'value' => $limits, |
| 359 | ); |
| 360 | } |
| 361 | |
| 362 | // Get GD information, if available. |
| 363 | if ( function_exists( 'gd_info' ) ) { |
| 364 | $gd = gd_info(); |
| 365 | } else { |
| 366 | $gd = false; |
| 367 | } |
| 368 | $info['wp-media']['fields'][] = array( |
| 369 | 'label' => __( 'GD Version' ), |
| 370 | 'value' => ( is_array( $gd ) ? $gd['GD Version'] : 'GD not available' ), |
| 371 | ); |
| 372 | |
| 373 | // Get Ghostscript information, if available. |
| 374 | if ( function_exists( 'exec' ) ) { |
| 375 | $gs = exec( 'gs --version' ); |
| 376 | $gs = ( ! empty( $gs ) ? $gs : 'Not available' ); |
| 377 | } else { |
| 378 | $gs = __( 'Unable to determine if Ghostscript is installed' ); |
| 379 | } |
| 380 | $info['wp-media']['fields'][] = array( |
| 381 | 'label' => __( 'Ghostscript Version' ), |
| 382 | 'value' => $gs, |
| 383 | ); |
| 384 | |
| 385 | // Populate the server debug fields. |
| 386 | $info['wp-server']['fields'][] = array( |
| 387 | 'label' => __( 'Server architecture' ), |
| 388 | 'value' => ( ! function_exists( 'php_uname' ) ? __( 'Unable to determine server architecture' ) : sprintf( '%s %s %s', php_uname( 's' ), php_uname( 'r' ), php_uname( 'm' ) ) ), |
| 389 | ); |
| 390 | $info['wp-server']['fields'][] = array( |
| 391 | 'label' => __( 'PHP Version' ), |
| 392 | 'value' => ( ! function_exists( 'phpversion' ) ? __( 'Unable to determine PHP version' ) : sprintf( |
| 393 | '%s %s', |
| 394 | phpversion(), |
| 395 | ( 64 === PHP_INT_SIZE * 8 ? __( '(Supports 64bit values)' ) : '' ) |
| 396 | ) |
| 397 | ), |
| 398 | ); |
| 399 | $info['wp-server']['fields'][] = array( |
| 400 | 'label' => __( 'PHP SAPI' ), |
| 401 | 'value' => ( ! function_exists( 'php_sapi_name' ) ? __( 'Unable to determine PHP SAPI' ) : php_sapi_name() ), |
| 402 | ); |
| 403 | |
| 404 | if ( ! function_exists( 'ini_get' ) ) { |
| 405 | $info['wp-server']['fields'][] = array( |
| 406 | 'label' => __( 'Server settings' ), |
| 407 | 'value' => __( 'Unable to determine some settings as the ini_get() function has been disabled' ), |
| 408 | ); |
| 409 | } else { |
| 410 | $info['wp-server']['fields'][] = array( |
| 411 | 'label' => __( 'PHP max input variables' ), |
| 412 | 'value' => ini_get( 'max_input_vars' ), |
| 413 | ); |
| 414 | $info['wp-server']['fields'][] = array( |
| 415 | 'label' => __( 'PHP time limit' ), |
| 416 | 'value' => ini_get( 'max_execution_time' ), |
| 417 | ); |
| 418 | $info['wp-server']['fields'][] = array( |
| 419 | 'label' => __( 'PHP memory limit' ), |
| 420 | 'value' => ini_get( 'memory_limit' ), |
| 421 | ); |
| 422 | $info['wp-server']['fields'][] = array( |
| 423 | 'label' => __( 'Max input time' ), |
| 424 | 'value' => ini_get( 'max_input_time' ), |
| 425 | ); |
| 426 | $info['wp-server']['fields'][] = array( |
| 427 | 'label' => __( 'Upload max filesize' ), |
| 428 | 'value' => ini_get( 'upload_max_filesize' ), |
| 429 | ); |
| 430 | $info['wp-server']['fields'][] = array( |
| 431 | 'label' => __( 'PHP post max size' ), |
| 432 | 'value' => ini_get( 'post_max_size' ), |
| 433 | ); |
| 434 | } |
| 435 | |
| 436 | if ( function_exists( 'curl_version' ) ) { |
| 437 | $curl = curl_version(); |
| 438 | $info['wp-server']['fields'][] = array( |
| 439 | 'label' => __( 'cURL Version' ), |
| 440 | 'value' => sprintf( '%s %s', $curl['version'], $curl['ssl_version'] ), |
| 441 | ); |
| 442 | } else { |
| 443 | $info['wp-server']['fields'][] = array( |
| 444 | 'label' => __( 'cURL Version' ), |
| 445 | 'value' => __( 'Your server does not support cURL' ), |
| 446 | ); |
| 447 | } |
| 448 | |
| 449 | $info['wp-server']['fields'][] = array( |
| 450 | 'label' => __( 'SUHOSIN installed' ), |
| 451 | 'value' => ( ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ) ? __( 'Yes' ) : __( 'No' ) ), |
| 452 | ); |
| 453 | |
| 454 | $info['wp-server']['fields'][] = array( |
| 455 | 'label' => __( 'Is the Imagick library available' ), |
| 456 | 'value' => ( extension_loaded( 'imagick' ) ? __( 'Yes' ) : __( 'No' ) ), |
| 457 | ); |
| 458 | |
| 459 | // Populate the database debug fields. |
| 460 | if ( is_resource( $wpdb->dbh ) ) { |
| 461 | // Old mysql extension. |
| 462 | $extension = 'mysql'; |
| 463 | } elseif ( is_object( $wpdb->dbh ) ) { |
| 464 | // mysqli or PDO. |
| 465 | $extension = get_class( $wpdb->dbh ); |
| 466 | } else { |
| 467 | // Unknown sql extension. |
| 468 | $extension = null; |
| 469 | } |
| 470 | |
| 471 | if ( method_exists( $wpdb, 'db_version' ) ) { |
| 472 | if ( $wpdb->use_mysqli ) { |
| 473 | $server = mysqli_get_server_info( $wpdb->dbh ); |
| 474 | } else { |
| 475 | $server = mysql_get_server_info( $wpdb->dbh ); |
| 476 | } |
| 477 | } else { |
| 478 | $server = null; |
| 479 | } |
| 480 | |
| 481 | if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) { |
| 482 | $client_version = $wpdb->dbh->client_info; |
| 483 | } else { |
| 484 | if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) { |
| 485 | $client_version = $matches[0]; |
| 486 | } else { |
| 487 | $client_version = null; |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | $info['wp-database']['fields'][] = array( |
| 492 | 'label' => __( 'Extension' ), |
| 493 | 'value' => $extension, |
| 494 | ); |
| 495 | $info['wp-database']['fields'][] = array( |
| 496 | 'label' => __( 'Server version' ), |
| 497 | 'value' => $server, |
| 498 | ); |
| 499 | $info['wp-database']['fields'][] = array( |
| 500 | 'label' => __( 'Client version' ), |
| 501 | 'value' => $client_version, |
| 502 | ); |
| 503 | $info['wp-database']['fields'][] = array( |
| 504 | 'label' => __( 'Database user' ), |
| 505 | 'value' => $wpdb->dbuser, |
| 506 | 'private' => true, |
| 507 | ); |
| 508 | $info['wp-database']['fields'][] = array( |
| 509 | 'label' => __( 'Database host' ), |
| 510 | 'value' => $wpdb->dbhost, |
| 511 | 'private' => true, |
| 512 | ); |
| 513 | $info['wp-database']['fields'][] = array( |
| 514 | 'label' => __( 'Database name' ), |
| 515 | 'value' => $wpdb->dbname, |
| 516 | 'private' => true, |
| 517 | ); |
| 518 | $info['wp-database']['fields'][] = array( |
| 519 | 'label' => __( 'Database prefix' ), |
| 520 | 'value' => $wpdb->prefix, |
| 521 | ); |
| 522 | |
| 523 | |
| 524 | // List must use plugins if there are any. |
| 525 | $mu_plugins = get_mu_plugins(); |
| 526 | |
| 527 | foreach ( $mu_plugins as $plugin_path => $plugin ) { |
| 528 | $plugin_version = $plugin['Version']; |
| 529 | $plugin_author = $plugin['Author']; |
| 530 | |
| 531 | $plugin_version_string = __( 'No version or author information available' ); |
| 532 | |
| 533 | if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) { |
| 534 | // translators: %1$s: Plugin version number. %2$s: Plugin author name. |
| 535 | $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author ); |
| 536 | } |
| 537 | if ( empty( $plugin_version ) && ! empty( $plugin_author ) ) { |
| 538 | // translators: %s: Plugin author name. |
| 539 | $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author ); |
| 540 | } |
| 541 | if ( ! empty( $plugin_version ) && empty( $plugin_author ) ) { |
| 542 | // translators: %s: Plugin version number. |
| 543 | $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version ); |
| 544 | } |
| 545 | |
| 546 | $info['wp-mu-plugins']['fields'][] = array( |
| 547 | 'label' => $plugin['Name'], |
| 548 | 'value' => $plugin_version_string, |
| 549 | ); |
| 550 | } |
| 551 | |
| 552 | // List all available plugins. |
| 553 | $plugins = get_plugins(); |
| 554 | $plugin_updates = get_plugin_updates(); |
| 555 | |
| 556 | foreach ( $plugins as $plugin_path => $plugin ) { |
| 557 | $plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive'; |
| 558 | |
| 559 | $plugin_version = $plugin['Version']; |
| 560 | $plugin_author = $plugin['Author']; |
| 561 | |
| 562 | $plugin_version_string = __( 'No version or author information available' ); |
| 563 | |
| 564 | if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) { |
| 565 | // translators: %1$s: Plugin version number. %2$s: Plugin author name. |
| 566 | $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author ); |
| 567 | } |
| 568 | if ( empty( $plugin_version ) && ! empty( $plugin_author ) ) { |
| 569 | // translators: %s: Plugin author name. |
| 570 | $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author ); |
| 571 | } |
| 572 | if ( ! empty( $plugin_version ) && empty( $plugin_author ) ) { |
| 573 | // translators: %s: Plugin version number. |
| 574 | $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version ); |
| 575 | } |
| 576 | |
| 577 | if ( array_key_exists( $plugin_path, $plugin_updates ) ) { |
| 578 | // translators: %s: Latest plugin version number. |
| 579 | $plugin_update_needed = ' ' . sprintf( __( '( Latest version: %s )' ), $plugin_updates[ $plugin_path ]->update->new_version ); |
| 580 | } else { |
| 581 | $plugin_update_needed = ''; |
| 582 | } |
| 583 | |
| 584 | $info[ $plugin_part ]['fields'][] = array( |
| 585 | 'label' => $plugin['Name'], |
| 586 | 'value' => $plugin_version_string . $plugin_update_needed, |
| 587 | ); |
| 588 | } |
| 589 | |
| 590 | // Populate the section for the currently active theme. |
| 591 | global $_wp_theme_features; |
| 592 | $theme_features = array(); |
| 593 | if ( ! empty( $_wp_theme_features ) ) { |
| 594 | foreach ( $_wp_theme_features as $feature => $options ) { |
| 595 | $theme_features[] = $feature; |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | $active_theme = wp_get_theme(); |
| 600 | $theme_updates = get_theme_updates(); |
| 601 | |
| 602 | if ( array_key_exists( $active_theme->stylesheet, $theme_updates ) ) { |
| 603 | // translators: %s: Latest theme version number. |
| 604 | $theme_update_needed_active = ' ' . sprintf( __( '( Latest version: %s )' ), $theme_updates[ $active_theme->stylesheet ]->update['new_version'] ); |
| 605 | } else { |
| 606 | $theme_update_needed_active = ''; |
| 607 | } |
| 608 | |
| 609 | $info[ 'wp-active-theme']['fields'] = array( |
| 610 | array( |
| 611 | 'label' => __( 'Name' ), |
| 612 | 'value' => $active_theme->Name, |
| 613 | ), |
| 614 | array( |
| 615 | 'label' => __( 'Version' ), |
| 616 | 'value' => $active_theme->Version . $theme_update_needed_active, |
| 617 | ), |
| 618 | array( |
| 619 | 'label' => __( 'Author' ), |
| 620 | 'value' => wp_kses( $active_theme->Author, array() ), |
| 621 | ), |
| 622 | array( |
| 623 | 'label' => __( 'Author website' ), |
| 624 | 'value' => ( $active_theme->offsetGet( 'Author URI' ) ? $active_theme->offsetGet( 'Author URI' ) : __( 'Undefined' ) ), |
| 625 | ), |
| 626 | array( |
| 627 | 'label' => __( 'Parent theme' ), |
| 628 | 'value' => ( $active_theme->parent_theme ? $active_theme->parent_theme : __( 'Not a child theme' ) ), |
| 629 | ), |
| 630 | array( |
| 631 | 'label' => __( 'Supported theme features' ), |
| 632 | 'value' => implode( ', ', $theme_features ), |
| 633 | ), |
| 634 | ); |
| 635 | |
| 636 | // Populate a list of all themes available in the install. |
| 637 | $all_themes = wp_get_themes(); |
| 638 | |
| 639 | foreach ( $all_themes as $theme_slug => $theme ) { |
| 640 | // Ignore the currently active theme from the list of all themes. |
| 641 | if ( $active_theme->stylesheet === $theme_slug ) { |
| 642 | continue; |
| 643 | } |
| 644 | |
| 645 | $theme_version = $theme->Version; |
| 646 | $theme_author = $theme->Author; |
| 647 | |
| 648 | $theme_version_string = __( 'No version or author information available' ); |
| 649 | |
| 650 | if ( ! empty( $theme_version ) && ! empty( $theme_author ) ) { |
| 651 | // translators: %1$s: Theme version number. %2$s: Theme author name. |
| 652 | $theme_version_string = sprintf( __( 'Version %1$s by %2$s' ), $theme_version, wp_kses( $theme_author, array() ) ); |
| 653 | } |
| 654 | if ( empty( $theme_version ) && ! empty( $theme_author ) ) { |
| 655 | // translators: %s: Theme author name. |
| 656 | $theme_version_string = sprintf( __( 'By %s' ), wp_kses( $theme_author, array() ) ); |
| 657 | } |
| 658 | if ( ! empty( $theme_version ) && empty( $theme_author ) ) { |
| 659 | // translators: %s: Theme version number. |
| 660 | $theme_version_string = sprintf( __( 'Version %s' ), $theme_version ); |
| 661 | } |
| 662 | |
| 663 | if ( array_key_exists( $theme_slug, $theme_updates ) ) { |
| 664 | // translators: %s: Latest theme version number. |
| 665 | $theme_update_needed = ' ' . sprintf( __( '( Latest version: %s )' ), $theme_updates[ $theme_slug ]->update['new_version'] ); |
| 666 | } else { |
| 667 | $theme_update_needed = ''; |
| 668 | } |
| 669 | |
| 670 | $info['wp-themes']['fields'][] = array( |
| 671 | // translators: %1$s: Theme name. %2$s: Theme slug. |
| 672 | 'label' => sprintf( __( '%1$s (%2$s)' ), $theme->Name, $theme_slug ), |
| 673 | 'value' => $theme_version_string . $theme_update_needed, |
| 674 | ); |
| 675 | } |
| 676 | |
| 677 | // Add more filesystem checks. |
| 678 | if ( defined( 'WPMU_PLUGIN_DIR' ) && is_dir( WPMU_PLUGIN_DIR ) ) { |
| 679 | $info['wp-filesystem']['fields'][] = array( |
| 680 | 'label' => __( 'The Must Use Plugins directory' ), |
| 681 | 'value' => ( wp_is_writable( WPMU_PLUGIN_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ), |
| 682 | ); |
| 683 | } |
| 684 | |
| 685 | /** |
| 686 | * Add or modify new debug sections. |
| 687 | * |
| 688 | * Plugin or themes may wish to introduce their own debug information without creating additional admin pages for this |
| 689 | * kind of information as it is rarely needed, they can then utilize this filter to introduce their own sections. |
| 690 | * |
| 691 | * This filter intentionally does not include the fields introduced by core as those should always be un-modified |
| 692 | * and reliable for support related scenarios, take note that the core fields will take priority if a filtered value |
| 693 | * is trying to use the same array keys. |
| 694 | * |
| 695 | * Array keys added by core are all prefixed with `wp-`, plugins and themes are encouraged to use their own slug as |
| 696 | * a prefix, both for consistency as well as avoiding key collisions. |
| 697 | * |
| 698 | * @since 5.0.0 |
| 699 | * |
| 700 | * @param array $args { |
| 701 | * The debug information to be added to the core information page. |
| 702 | * |
| 703 | * @type string $label The title for this section of the debug output. |
| 704 | * @type string $description Optional. A description for your information section which may contain basic HTML |
| 705 | * markup: `em`, `strong` and `a` for linking to documentation or putting emphasis. |
| 706 | * @type boolean $show_count Optional. If set to `true` the amount of fields will be included in the title for |
| 707 | * this section. |
| 708 | * @type boolean $private Optional. If set to `true` the section and all associated fields will be excluded |
| 709 | * from the copy-paste text area. |
| 710 | * @type array $fields { |
| 711 | * An associative array containing the data to be displayed. |
| 712 | * |
| 713 | * @type string $label The label for this piece of information. |
| 714 | * @type string $value The output that is of interest for this field. |
| 715 | * @type boolean $private Optional. If set to `true` the field will not be included in the copy-paste text area |
| 716 | * on top of the page, allowing you to show, for example, API keys here. |
| 717 | * } |
| 718 | * } |
| 719 | */ |
| 720 | $external_info = apply_filters( 'debug_information', array() ); |
| 721 | |
| 722 | // Merge the core and external debug fields. |
| 723 | $info = array_replace_recursive( $info, array_replace_recursive( $external_info, $info ) ); |
| 724 | ?> |
| 725 | |
| 726 | <div class="notice notice-info"> |
| 727 | <p> |
| 728 | <?php esc_html_e( 'The system information shown below can also be copied and pasted into support requests such as on the WordPress.org forums, or to your theme and plugin developers.' ); ?> |
| 729 | </p> |
| 730 | <p> |
| 731 | <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-wrapper').style.display = 'block'; this.style.display = 'none';"><?php esc_html_e( 'Show copy and paste field' ); ?></button> |
| 732 | </p> |
| 733 | |
| 734 | <div id="system-information-copy-wrapper" style="display: none;"> |
| 735 | <textarea id="system-information-copy-field" class="widefat" rows="10">` |
| 736 | <?php |
| 737 | foreach ( $info as $section => $details ) { |
| 738 | // Skip this section if there are no fields, or the section has been declared as private. |
| 739 | if ( empty( $details['fields'] ) || ( isset( $details['private'] ) && $details['private'] ) ) { |
| 740 | continue; |
| 741 | } |
| 742 | |
| 743 | printf( |
| 744 | "### %s%s ###\n\n", |
| 745 | esc_html( $details['label'] ), |
| 746 | ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' ) |
| 747 | ); |
| 748 | |
| 749 | foreach ( $details['fields'] as $field ) { |
| 750 | if ( isset( $field['private'] ) && true === $field['private'] ) { |
| 751 | continue; |
| 752 | } |
| 753 | |
| 754 | if ( is_array( $field['value'] ) ) { |
| 755 | $values = ''; |
| 756 | foreach ( $field['value'] as $subfield ) { |
| 757 | $values .= sprintf( |
| 758 | "\n\t %s: %s", |
| 759 | esc_html( $subfield['label'] ), |
| 760 | esc_html( $subfield['value'] ) |
| 761 | ); |
| 762 | } |
| 763 | } else { |
| 764 | $values = esc_html( $field['value'] ); |
| 765 | } |
| 766 | |
| 767 | printf( |
| 768 | "%s: %s\n", |
| 769 | esc_html( $field['label'] ), |
| 770 | $values |
| 771 | ); |
| 772 | } |
| 773 | echo "\n"; |
| 774 | } |
| 775 | ?> |
| 776 | </textarea> |
| 777 | <p> |
| 778 | <?php esc_html_e( 'Some information may be filtered out from the list you are about to copy, this is information that may be considered private, and is not meant to be shared in a public forum.' ); ?> |
| 779 | <br> |
| 780 | <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-field').select(); document.execCommand( 'copy' );"><?php esc_html_e( 'Copy' ); ?></button> |
| 781 | </p> |
| 782 | </div> |
| 783 | </div> |
| 784 | |
| 785 | <div id="system-information-table-of-contents"> |
| 786 | <?php |
| 787 | $toc = array(); |
| 788 | |
| 789 | foreach ( $info as $section => $details ) { |
| 790 | if ( empty( $details['fields'] ) ) { |
| 791 | continue; |
| 792 | } |
| 793 | |
| 794 | $toc[] = sprintf( |
| 795 | '<a href="#%s" class="debug-toc">%s</a>', |
| 796 | esc_attr( $section ), |
| 797 | esc_html( $details['label'] ) |
| 798 | ); |
| 799 | } |
| 800 | |
| 801 | echo implode( ' | ', $toc ); |
| 802 | ?> |
| 803 | </div> |
| 804 | |
| 805 | <?php |
| 806 | foreach ( $info as $section => $details ) { |
| 807 | if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) { |
| 808 | continue; |
| 809 | } |
| 810 | |
| 811 | printf( |
| 812 | '<h2 id="%s">%s%s</h2>', |
| 813 | esc_attr( $section ), |
| 814 | esc_html( $details['label'] ), |
| 815 | ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' ) |
| 816 | ); |
| 817 | |
| 818 | if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) { |
| 819 | printf( |
| 820 | '<p>%s</p>', |
| 821 | wp_kses( $details['description'], array( |
| 822 | 'a' => array( |
| 823 | 'href' => true, |
| 824 | ), |
| 825 | 'strong' => true, |
| 826 | 'em' => true, |
| 827 | ) ) |
| 828 | ); |
| 829 | } |
| 830 | ?> |
| 831 | <table class="widefat striped"> |
| 832 | <tbody> |
| 833 | <?php |
| 834 | foreach ( $details['fields'] as $field ) { |
| 835 | if ( is_array( $field['value'] ) ) { |
| 836 | $values = ''; |
| 837 | foreach ( $field['value'] as $item ) { |
| 838 | $values .= sprintf( |
| 839 | '<li>%s: %s</li>', |
| 840 | esc_html( $item['label'] ), |
| 841 | esc_html( $item['value'] ) |
| 842 | ); |
| 843 | } |
| 844 | } else { |
| 845 | $values = esc_html( $field['value'] ); |
| 846 | } |
| 847 | |
| 848 | printf( |
| 849 | '<tr><td>%s</td><td>%s</td></tr>', |
| 850 | esc_html( $field['label'] ), |
| 851 | $values |
| 852 | ); |
| 853 | } |
| 854 | ?> |
| 855 | </tbody> |
| 856 | </table> |
| 857 | <span style="display: block; width: 100%; text-align: <?php echo ( is_rtl() ? 'left' : 'right' ); ?>"> |
| 858 | <a href="#system-information-table-of-contents" class="debug-toc"><?php esc_html_e( 'Return to table of contents' ); ?></a> |
| 859 | </span> |
| 860 | <?php |
| 861 | } |
| 862 | } else { |
| 863 | if ( ! function_exists( 'phpinfo' ) ) { |
| 864 | ?> |
| 865 | |
| 866 | <div class="notice notice-error"> |
| 867 | <p> |
| 868 | <?php esc_html_e( 'The phpinfo() function has been disabled by your host. Please contact the host if you need more information about your setup.' ); ?> |
| 869 | </p> |
| 870 | </div> |
| 871 | |
| 872 | <?php } else { ?> |
| 873 | |
| 874 | <div class="notice notice-warning"> |
| 875 | <p> |
| 876 | <?php esc_html_e( 'Some scenarios require you to look up more detailed server configurations than what is normally required. This page allows you to view all available configuration options for your PHP setup. Please be advised that WordPress does not guarantee that any information shown on this page may not be considered private.' ); ?> |
| 877 | </p> |
| 878 | </div> |
| 879 | |
| 880 | <?php |
| 881 | ob_start(); |
| 882 | phpinfo(); |
| 883 | $phpinfo_raw = ob_get_clean(); |
| 884 | |
| 885 | // Extract the body of the `phpinfo()` call, to avoid all the styles they introduce. |
| 886 | preg_match_all( '/<body[^>]*>(.*)<\/body>/siU', $phpinfo_raw, $phpinfo ); |
| 887 | |
| 888 | // Extract the styles `phpinfo()` creates for this page. |
| 889 | preg_match_all( '/<style[^>]*>(.*)<\/style>/siU', $phpinfo_raw, $styles ); |
| 890 | |
| 891 | // We remove various styles that break the visual flow of wp-admin. |
| 892 | $remove_patterns = array( |
| 893 | "/a:.+?\n/si", |
| 894 | "/body.+?\n/si", |
| 895 | ); |
| 896 | |
| 897 | // Output the styles as an inline style block. |
| 898 | if ( isset( $styles[1][0] ) ) { |
| 899 | $styles = preg_replace( $remove_patterns, '', $styles[1][0] ); |
| 900 | echo '<style type="text/css">' . $styles . '</style>'; |
| 901 | } |
| 902 | |
| 903 | // Output the actual phpinfo data. |
| 904 | if ( isset( $phpinfo[1][0] ) ) { |
| 905 | echo $phpinfo[1][0]; |
| 906 | } |
| 907 | ?> |
| 908 | |
| 909 | <?php } ?> |
| 910 | |
| 911 | <?php } ?> |
| 912 | </div> |
| 913 | |
| 914 | <script type="text/javascript"> |
| 915 | jQuery(document).ready( function( $ ) { |
| 916 | $(".debug-toc").click( function( e ) { |
| 917 | e.preventDefault(); |
| 918 | // Remove the height of the admin bar, and an extra 10px for better positioning. |
| 919 | var offset = $( $(this).attr('href') ).offset().top - $("#wpadminbar").height() - 10; |
| 920 | $('html, body').animate({ |
| 921 | scrollTop: offset |
| 922 | }, 1200); |
| 923 | }); |
| 924 | }); |
| 925 | </script> |
| 926 | |
| 927 | <?php |
| 928 | require ABSPATH . 'wp-admin/admin-footer.php'; |