Index: src/wp-admin/info.php
===================================================================
--- src/wp-admin/info.php	(revision)
+++ src/wp-admin/info.php	(revision)
@@ -0,0 +1,417 @@
+<?php
+/**
+ * Get system status for debugging and support.
+ *
+ * @package WordPress
+ * @subpackage Administration
+ */
+
+/** WordPress Administration Bootstrap */
+require_once( dirname( __FILE__ ) . '/admin.php' );
+
+if ( ! is_super_admin() ) {
+	wp_die( __( 'Sorry, you do not have permission to access this page.' ) );
+}
+
+global $wpdb;
+
+$title = __( 'System information' );
+
+require_once( ABSPATH . 'wp-admin/admin-header.php' );
+
+$info = array(
+	'WordPress'        => array(
+		'fields'      => array(
+			array(
+				'label' => 'Version',
+				'value' => get_bloginfo( 'version' )
+			),
+			array(
+				'label' => 'Debug mode',
+				'value' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) )
+			),
+			array(
+				'label' => 'Language',
+				'value' => get_locale()
+			),
+			array(
+				'label' => 'Home URL',
+				'value' => get_bloginfo( 'url' ),
+				'private' => true
+			),
+			array(
+				'label' => 'Site URL',
+				'value' => get_bloginfo( 'wpurl' ),
+				'private' => true
+			),
+			array(
+				'label' => 'Home path',
+				'value' => get_home_path(),
+				'private' => true
+			),
+			array(
+				'label' => 'HTTPS',
+				'value' => ( is_ssl() ? 'Enabled' : 'Disabled' )
+			),
+			array(
+				'label' => 'Theme directory is writable',
+				'value' => ( wp_is_writable( TEMPLATEPATH . '/..' ) ? __( 'Yes' ) : __( 'No' ) )
+			),
+			array(
+				'label' => 'Plugin directory is writable',
+				'value' => ( wp_is_writable( WP_PLUGIN_DIR ) ? __( 'Yes' ) : __( 'No' ) )
+			),
+			array(
+				'label' => 'WordPress memory limit',
+				'value' => WP_MAX_MEMORY_LIMIT
+			),
+			array(
+				'label' => 'Multisite',
+				'value' => ( is_multisite() ? __( 'Yes' ) : __( 'No' ) )
+			)
+		),
+	),
+	'Active theme'     => array(
+		'fields' => array()
+	),
+	'Available themes'     => array(
+		'fields'	=> array(),
+		'show_count'	=> true
+	),
+	'Must Use Plugins' => array(
+		'fields' 	=> array(),
+		'show_count'	=> true
+	),
+	'Active plugins'          => array(
+		'fields'	=> array(),
+		'show_count'	=> true
+	),
+	'Inactive plugins'          => array(
+		'fields'	=> array(),
+		'show_count'	=> true
+	),
+	'Server'           => array(
+		'description'	=> __( 'The options shown below are relating to your server setup, and may require the help of your host if changes are required.' ),
+		'fields'	=> array()
+	),
+	'Database'         => array(
+		'fields'	=> array()
+	)
+);
+
+if ( is_multisite() ) {
+	$network_query = new WP_Network_Query();
+	$network_ids = $network_query->query( array(
+		'fields'        => 'ids',
+		'number'        => 100,
+		'no_found_rows' => false,
+	) );
+
+	$site_count = 0;
+	foreach ( $network_ids as $network_id ) {
+		$site_count += get_blog_count( $network_id );
+	}
+
+	$info['WordPress']['fields'][] = array(
+		'label' => 'User Count',
+		'value' => get_user_count()
+	);
+	$info['WordPress']['fields'][] = array(
+		'label' => 'Site Count',
+		'value' => $site_count
+	);
+	$info['WordPress']['fields'][] = array(
+		'label' => 'Network Count',
+		'value' => $network_query->found_networks
+	);
+} else {
+	$user_count = count_users();
+
+	$info['WordPress']['fields'][] = array(
+		'label' => 'User Count',
+		'value' => $user_count['total_users']
+	);
+}
+
+// Populate the server debug fields
+$info['Server']['fields'][] = array(
+	'label' => 'PHP Version',
+	'value' => phpversion()
+);
+$info['Server']['fields'][] = array(
+	'label' => 'PHP SAPI',
+	'value' => php_sapi_name()
+);
+$info['Server']['fields'][] = array(
+	'label' => 'PHP post max size',
+	'value' => ini_get( 'post_max_size' )
+);
+$info['Server']['fields'][] = array(
+	'label' => 'PHP time limit',
+	'value' => ini_get( 'max_execution_time' )
+);
+$info['Server']['fields'][] = array(
+	'label' => 'PHP memory limit',
+	'value' => ini_get( 'memory_limit' )
+);
+
+$cURL = curl_version();
+$info['Server']['fields'][] = array(
+	'label' => 'cURL Version',
+	'value' => sprintf( '%s %s', $cURL['version'], $cURL['ssl_version'] )
+);
+
+$info['Server']['fields'][] = array(
+	'label' => 'SUHOSIN installed',
+	'value' => ( ( extension_loaded('suhosin') || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ) ? __( 'Yes' ) : __( 'No' ) )
+);
+
+
+// Populate the database debug fields.
+if ( is_resource( $wpdb->dbh ) ) {
+	# Old mysql extension
+	$extension = 'mysql';
+} else if ( is_object( $wpdb->dbh ) ) {
+	# mysqli or PDO
+	$extension = get_class( $wpdb->dbh );
+} else {
+	# Who knows?
+	$extension = null;
+}
+
+if ( method_exists( $wpdb, 'db_version' ) ) {
+	$server = $wpdb->db_version();
+} else {
+	$server = null;
+}
+
+if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
+	$client_version = mysqli_get_client_version();
+} else {
+	if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
+		$client_version = $matches[0];
+	} else {
+		$client_version = null;
+	}
+}
+
+$info['Database']['fields'][] = array(
+	'label' => 'Extension',
+	'value' => $extension
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Server version',
+	'value' => $server
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Client version',
+	'value' => $client_version
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Database user',
+	'value' => $wpdb->dbuser,
+	'private' => true
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Database host',
+	'value' => $wpdb->dbhost,
+	'private' => true
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Database table',
+	'value' => $wpdb->dbname,
+	'private' => true
+);
+$info['Database']['fields'][] = array(
+	'label' => 'Database prefix',
+	'value' => $wpdb->prefix
+);
+
+
+// List must use plugins if there are any
+$mu_plugins = get_mu_plugins();
+
+foreach ( $mu_plugins AS $plugin_path => $plugin ) {
+	$info['Must Use Plugins']['fields'][] = array(
+		'label' => $plugin['Name'],
+		'value' => sprintf( 'Version %s by %s', $plugin['Version'], $plugin['Author'] )
+	);
+}
+
+
+// List active- and inactive plugins
+$plugins = get_plugins();
+
+foreach ( $plugins AS $plugin_path => $plugin ) {
+
+	$key = ( is_plugin_active( $plugin_path ) ) ? 'Active plugins' : 'Inactive plugins'; 
+
+	$info[$key]['fields'][] = array(
+		'label' => $plugin['Name'],
+		'value' => sprintf( 'Version %s by %s', $plugin['Version'], $plugin['Author'] )
+	);
+}
+
+
+// Populate the section for the currently active theme
+$theme = wp_get_theme();
+
+$info['Active theme']['fields'] = array(
+	array(
+		'label' => 'Name',
+		'value' => $theme->Name
+	),
+	array(
+		'label' => 'Version',
+		'value' => $theme->Version
+	),
+	array(
+		'label' => 'Author',
+		'value' => wp_kses( $theme->Author, array() )
+	),
+	array(
+		'label' => 'Author URL',
+		'value' => $theme->AuthorURI
+	),
+	array(
+		'label' => 'Parent theme',
+		'value' => ( $theme->parent_Theme ?: 'Not a child theme' )
+	)
+);
+
+
+// Populate a list of all themes available in the install
+$all_themes = wp_get_themes();
+
+foreach ( $all_themes AS $theme_slug => $theme ) {
+	$info['Available themes']['fields'][] = array(
+		'label' => sprintf( '%s (%s)', $theme->Name, $theme_slug ),
+		'value' => sprintf( 'Version %s by %s', $theme->Version, wp_kses( $theme->Author, array() ) )
+	);
+}
+
+
+/**
+ * Add or modify new debug sections.
+ *
+ * Plugin or themes may wish to introduce their own debug information without creating additional admin pages for this
+ * kind of information as it is rarely needed, they can then utilize this filter to introduce their own sections.
+ *
+ * This filter intentionally does not include the fields introduced by core as those should always be un-modified
+ * and reliable for support related scenarios.
+ *
+ * @since 4.9.0
+ *
+ * @param array $args {
+ *     The debug information to be added to the core information page.
+ *
+ *     @type string $description Optional. A description for your information section which may contain basic HTML
+ *                               markup: `em`, `strong` and `a` for linking to documentation or putting emphasis.
+ *     @type array  $fields      {
+ *         An associative array containing the data to be displayed.
+ *
+ *         @type string  $label   The label for this piece of information.
+ *         @type string  $value   The output that is of interest for this field.
+ *         @type boolean $private Optional. If set to `true` the field will not be included in the copy-paste text area
+ *                                on top of the page, allowing you to show, for example, API keys here.
+ *     }
+ * }
+ */
+$external_info = apply_filters( 'debug_information', array() );
+
+// Merge the core and external debug fields
+$info = array_merge( $external_info, $info );
+?>
+
+<div class="wrap">
+	<h1 class="wp-heading-inline">
+		<?php echo esc_html( $title ); ?>
+	</h1>
+
+	<label for="info-copy-paste-field">
+		<?php esc_html_e( 'Copy and paste' ); ?>
+	</label>
+	<textarea id="info-copy-paste-field" class="widefat">`
+<?php
+	foreach( $info as $section => $details ) {
+
+		if( isset( $details['show_count'] ) && true === $details['show_count'] ) {
+			printf( 
+				"%s (%d)\n", 
+				$section,
+				count( $details['fields'] )
+			);
+		} else {
+			printf( 
+				"%s\n", 
+				$section
+			);
+		}
+
+		foreach( $details['fields'] as $field ) {
+
+			if ( isset( $field['private'] ) && true === $field['private'] ) {
+				continue;
+			}
+
+			printf(
+				"%s: %s\n",
+				$field['label'],
+				$field['value']
+			);
+		}
+		echo "\n";
+	}
+?>
+`</textarea>
+
+<?php
+	foreach ( $info AS $section => $details ) {
+
+		if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) {
+			continue;
+		}
+
+		if( isset( $details['show_count'] ) && true === $details['show_count'] ) {
+			printf(
+				'<h2>%s (%d)</h2>',
+				esc_html( $section ),
+				count( $details['fields'] )
+			);
+		} else {
+			printf(
+				'<h2>%s</h2>',
+				esc_html( $section )
+			);
+		}
+
+		if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) {
+			printf(
+				'<p>%s</p>',
+				wp_kses( $details['description'], array(
+					'a' => array(
+						'href' => true
+					),
+					'strong' => true,
+					'em' => true,
+				) )
+			);
+		}
+		?>
+		<table class="widefat">
+			<tbody>
+			<?php
+			foreach ( $details['fields'] as $field ) {
+				printf(
+					'<tr><td>%s</td><td>%s</td></tr>',
+					esc_html( $field['label'] ),
+					esc_html( $field['value'] )
+				);
+			}
+			?>
+			</tbody>
+		</table>
+		<?php
+	}
+
+	include( ABSPATH . 'wp-admin/admin-footer.php' );
