Airstory page within WordPress.
*
* @package Airstory
*/
namespace Airstory\Tools;
/**
* Register the "Airstory" page under the Tools heading.
*/
function register_menu_page() {
add_submenu_page(
'tools.php',
_x( 'Airstory', 'tools page title', 'airstory' ),
_x( 'Airstory', 'tools menu title', 'airstory' ),
'manage_options',
'airstory',
__NAMESPACE__ . '\render_tools_page'
);
}
add_action( 'admin_menu', __NAMESPACE__ . '\register_menu_page' );
/**
* Register the tools scripting.
*/
function register_tools_script() {
wp_register_script(
'airstory-tools',
plugins_url( 'assets/js/tools.js', __DIR__ ),
null,
AIRSTORY_VERSION,
true
);
wp_localize_script( 'airstory-tools', 'airstoryTools', array(
'restApiUrl' => get_rest_url( null, '/airstory/v1', 'https' ),
'statusIcons' => array(
'loading' => '',
'success' => render_status_icon( true, false ),
'failure' => render_status_icon( false, false ),
),
) );
}
add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\register_tools_script' );
/**
* Render the content for the "Airstory" tools page.
*/
function render_tools_page() {
wp_enqueue_script( 'airstory-tools' );
$compatibility = check_compatibility();
?>
|
|
| = 5.3', 'airstory' ); ?> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
has a number of extensions available to enable new or improve existing functionality.', 'airstory' ) ); ?>
Liquid Web\'s Heroic Support; if you run into any issues when working with the Airstory plugin, please feel free to open an issue in the WordPress.org plugin repo.', 'airstory' ) ); ?>
%s',
esc_attr( $icon ),
esc_html( $msg )
);
if ( ! $echo ) {
return $output;
}
echo wp_kses_post( $output );
}
/**
* Verify the compatibility of the current environment with Airstory.
*
* The requirements for the plugin should be documented in the plugin README, but include:
*
* - PHP >= 5.3 - Namespace support, though the plugin will fail before reaching this check
* if namespaces are unsupported.
* - dom extension - Used by DOMDocument in formatters.php.
* - mcrypt extension - Used as a backup for older systems that don't support PHP 7's random_bytes().
* - openssl extension - Used to securely encrypt Airstory credentials.
*
* @return array {
* An array with two nodes, outlining any compatibility issues.
*
* @var bool $compatible Is the WordPress installation compatible with Airstory?
* @var array $details An array of dependency checks as keys, matched to an array containing
* 'compatible' (boolean) and 'explanation' (string) values.
* }
*/
function check_compatibility() {
$compatibility = array(
'compatible' => true,
'details' => array(),
);
// PHP Version.
$compatibility['details']['php'] = version_compare( PHP_VERSION, '5.3.0', '>=' );
if ( ! $compatibility['details']['php'] ) {
$compatibility['compatible'] = false;
}
// HTTPS support.
$compatibility['details']['https'] = verify_https_support();
if ( ! $compatibility['details']['https'] ) {
$compatibility['compatible'] = false;
}
// Check required PHP extensions.
$extensions = array( 'dom', 'mcrypt', 'openssl' );
foreach ( $extensions as $extension ) {
$compatibility['details'][ $extension ] = extension_loaded( $extension );
if ( ! $compatibility['details'][ $extension ] ) {
$compatibility['compatible'] = false;
}
}
return $compatibility;
}
/**
* Verify whether or not the current site *supports* HTTPS.
*
* The is_ssl() WordPress function checks if the current request was made over HTTPS, but does not
* take into account whether or not the request was made over HTTP but the site also supports SSL.
*
* For example, consider a site, example.com, that is running on both HTTP and HTTPS:
* - Running is_ssl() on https://example.com will return TRUE.
* - Running is_ssl() on http://example.com will return FALSE.
*
* If the site isn't already running on HTTPS, this function will attempt to ping the HTTPS version
* and return whether or not it was reachable.
*
* @return bool True if the site is either already being served (or is at least accessible) over
* HTTPS, false otherwise.
*/
function verify_https_support() {
if ( is_ssl() ) {
return true;
}
$response = wp_remote_request( get_rest_url( null, '/airstory/v1', 'https' ), array(
'method' => 'HEAD',
'sslverify' => false,
) );
if ( is_wp_error( $response ) ) {
return false;
}
/*
* 200 is the only status code we're looking for here — redirecting to the HTTP version will
* produced mixed-content warnings within Airstory, and WP's default behavior is to not redirect
* REST API URIs to use the canonical domain/protocol.
*/
return 200 === wp_remote_retrieve_response_code( $response );
}
/**
* Build a system environment report for submission along with any bug reports.
*
* This is largely based on (a simplified version) of Easy Digital Downloads' edd_tools_sysinfo_get()
* reporting function. Available for use in this plugin under the MIT license with permission from
* copyright holder Pippin Williamson.
*
* @link https://github.com/easydigitaldownloads/easy-digital-downloads
* @link https://github.com/liquidweb/airstory-wp/pull/35#discussion_r119388840
*
* @global $wpdb
*
* @return string A formatted text report on important details about the system status.
*/
function get_support_details() {
global $wpdb;
$report = '### Begin System Info ###' . PHP_EOL;
// Basic details about the site.
$report .= PHP_EOL . '-- Site Info' . PHP_EOL . PHP_EOL;
$report .= 'Site URL: ' . esc_url( site_url() ) . PHP_EOL;
$report .= 'Home URL: ' . esc_url( home_url() ) . PHP_EOL;
$report .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . PHP_EOL;
// What little user information might be relevant.
$report .= PHP_EOL . '-- User' . PHP_EOL . PHP_EOL;
$report .= 'User-Agent: ' . ( empty( $_SERVER['HTTP_USER_AGENT'] ) ? '(empty)' : esc_html( $_SERVER['HTTP_USER_AGENT'] ) ) . PHP_EOL;
// Basic WordPress configuration.
$theme_data = wp_get_theme();
$theme = sprintf( '%s %s', $theme_data->Name, $theme_data->Version );
$parent_theme = '(none)';
if ( ! empty( $theme_data->Template ) ) {
$parent_theme_data = wp_get_theme( $parent_theme );
$parent_theme = sprintf( '%s %s', $parent_theme_data->Name, $parent_theme_data->Version );
}
$report .= PHP_EOL . '-- WordPress Configuration' . PHP_EOL . PHP_EOL;
$report .= 'Version: ' . get_bloginfo( 'version' ) . PHP_EOL;
$report .= 'Language: ' . ( defined( 'WPLANG' ) && WPLANG ? WPLANG : 'en_US' ) . PHP_EOL;
$report .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . PHP_EOL;
$report .= 'Theme: ' . esc_html( $theme ) . PHP_EOL;
$report .= 'Parent Theme: ' . esc_html( $parent_theme ) . PHP_EOL;
$report .= 'ABSPATH: ' . ABSPATH . PHP_EOL;
$report .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) && WP_DEBUG ? 'Enabled' : 'Disabled' ) . PHP_EOL;
$report .= 'Memory Limit: ' . WP_MEMORY_LIMIT . PHP_EOL;
// Airstory-specific configuration.
$compatibility = check_compatibility();
$report .= PHP_EOL . '-- Airstory Configuration' . PHP_EOL . PHP_EOL;
$report .= 'Version: ' . AIRSTORY_VERSION . PHP_EOL;
$report .= 'Requirements:' . PHP_EOL;
$report .= '- PHP >= 5.3 ' . ( $compatibility['details']['php'] ? 'PASS' : 'FAIL' ) . PHP_EOL;
$report .= '- HTTPS support ' . ( $compatibility['details']['https'] ? 'PASS' : 'FAIL' ) . PHP_EOL;
$report .= '- DOM Extension ' . ( $compatibility['details']['dom'] ? 'PASS' : 'FAIL' ) . PHP_EOL;
$report .= '- Mcrypt Extension ' . ( $compatibility['details']['mcrypt'] ? 'PASS' : 'FAIL' ) . PHP_EOL;
$report .= '- OpenSSL Extension ' . ( $compatibility['details']['openssl'] ? 'PASS' : 'FAIL' ) . PHP_EOL;
// Plugins running on the site.
$all_plugins = get_plugins();
$mu_plugins = get_mu_plugins();
$active_plugins = get_option( 'active_plugins', array() );
$plugin_updates = get_plugin_updates();
if ( 0 < count( $mu_plugins ) ) {
$report .= PHP_EOL . '-- WordPress Plugins: Must-Use' . PHP_EOL . PHP_EOL;
foreach ( $mu_plugins as $mu_plugin ) {
$report .= sprintf( '- %s: %s', $mu_plugin['Name'], $mu_plugin['Version'] ) . PHP_EOL;
}
}
$report .= PHP_EOL . '-- WordPress Plugins: Active' . PHP_EOL . PHP_EOL;
foreach ( $all_plugins as $path => $plugin ) {
if ( ! in_array( $path, $active_plugins, true ) ) {
continue;
}
$report .= sprintf(
'- %s: %s%s',
$plugin['Name'],
$plugin['Version'],
array_key_exists( $path, $plugin_updates ) ? ' (update available)' : ''
) . PHP_EOL;
}
$report .= PHP_EOL . '-- WordPress Plugins: Inactive' . PHP_EOL . PHP_EOL;
foreach ( $all_plugins as $path => $plugin ) {
if ( in_array( $path, $active_plugins, true ) ) {
continue;
}
$report .= sprintf(
'- %s: %s%s',
$plugin['Name'],
$plugin['Version'],
array_key_exists( $path, $plugin_updates ) ? ' (update available)' : ''
) . PHP_EOL;
}
if ( is_multisite() ) {
$ms_all_plugins = wp_get_active_network_plugins();
$ms_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
$report .= PHP_EOL . '-- WordPress Plugins: Network Active' . PHP_EOL . PHP_EOL;
foreach ( $ms_all_plugins as $plugin_path ) {
$plugin_base = plugin_basename( $plugin_path );
if ( ! array_key_exists( $plugin_base, $active_ms_plugins ) ) {
continue;
}
$plugin = get_plugin_data( $plugin_path );
$report .= sprintf(
'- %s: %s%s',
$plugin['Name'],
$plugin['Version'],
array_key_exists( $path, $plugin_updates ) ? ' (update available)' : ''
) . PHP_EOL;
}
}
// Web server details.
$report .= PHP_EOL . '-- Server Configuration' . PHP_EOL . PHP_EOL;
$report .= 'PHP Version: ' . PHP_VERSION . PHP_EOL;
$report .= 'MySQL Version: ' . $wpdb->db_version() . PHP_EOL;
$report .= 'Web Server: ' . $_SERVER['SERVER_SOFTWARE'] . PHP_EOL;
// PHP Configuration.
$report .= PHP_EOL . '-- PHP Configuration' . PHP_EOL . PHP_EOL;
$report .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . PHP_EOL;
$report .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . PHP_EOL;
$report .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . PHP_EOL;
$report .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . PHP_EOL;
$report .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . PHP_EOL;
$report .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . PHP_EOL;
$report .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . PHP_EOL;
return $report . PHP_EOL . '### End System Info ###';
}