Skip to content

Instantly share code, notes, and snippets.

@bentideswell
Created October 20, 2022 09:43
Show Gist options
  • Save bentideswell/0f811e5f8ab0b767ae5f6e6fc7f805c0 to your computer and use it in GitHub Desktop.
Save bentideswell/0f811e5f8ab0b767ae5f6e6fc7f805c0 to your computer and use it in GitHub Desktop.
Provide debug information for a WordPress installation using FishPig. Especially useful for Multisite/Network installs.
<?php
/**
* @FishPig.com
*/
ini_set('display_errors', 1);
error_reporting(E_ALL);
$isCli = PHP_SAPI === 'cli';
define('DS', DIRECTORY_SEPARATOR);
try {
// Load WordPress code
_bootstrap_wordpress();
// Extract data we need for debugging
$data = [
// Get wp-config.php
// Remove DB_PASSWORD for security
'wp-config.php' => _get_wp_config_file(),
'.htaccess' => _get_htaccess_file(),
'data' => _get_data_from_database()
];
if (!$isCli) {
// If a browser, let's send a header
header('Content-Type: application/json;charset=utf-8');
}
echo json_encode($data);
} catch (\Exception $e) {
if ($isCli) {
echo $e->getMessage() . "\n\n" . $e->getTraceAsString() . "\n\n";
exit(1);
} else {
echo sprintf(
'<h1><span style="color:red;">Exception:</span> %s</h1><pre>%s</pre>',
$e->getMessage(),
$e->getTraceAsString()
);
}
}
/**
*
*/
function _bootstrap_wordpress(): void
{
$wpLoadFile = __DIR__ . DS . 'wp-load.php';
if (!is_file($wpLoadFile)) {
throw new \RuntimeException(
sprintf(
'Cannot find WordPress. Failed @ "%s"',
$wpLoadFile
)
);
}
require_once $wpLoadFile;
if (!defined('ABSPATH')) {
throw new \RuntimeException(
'Unable to find ABSPATH. WordPress bootstrap failed'
);
}
}
/**
* Try to get wp-config.phpfile
* If fails, return error message
* All data will be returned as a JSON string
* The password for the DB will be removed for security
*/
function _get_wp_config_file(): string
{
return _read_file(
ABSPATH . 'wp-config.php',
function ($data) {
// Remove Database password
return preg_replace(
'/(define\(\s*([\'"]{1})DB_PASSWORD\2\s*,\s*([\'"]{1}))[^\3]+(\3\s*\))/U',
'$1--REMOVED--$4',
$data
);
}
);
}
/**
* Get .htaccess file
*/
function _get_htaccess_file()
{
return _read_file(ABSPATH . '.htaccess');
}
/**
* Reads $file and handles errors
*/
function _read_file($file, \Closure $callback = null): string
{
if (!file_exists($file)) {
return [
'error' => sprintf('File does not exist @ "%s"', $file),
'source' => 'file_exists'
];
} elseif (!is_readable($file)) {
return [
'error' => sprintf('File is not readable @ "%s"', $file),
'source' => 'is_readable'
];
}
// Try to catch any errors
ob_start();
$data = @file_get_contents($file);
if ($output = ob_get_clean()) {
return [
'error' => (string)$output,
'source' => 'file_get_contents'
];
}
return is_callable($callback) ? $callback($data) : $data;
}
/**
*
*/
function _get_data_from_database(): array
{
global $wpdb;
$data = [
'is_multisite' => (int)is_multisite(),
'blogs' => []
];
$wpdb->show_errors = false;
try {
$blogs = $wpdb->get_results( "SELECT blog_id, domain, path FROM {$wpdb->prefix}blogs WHERE deleted = 0", ARRAY_A );
} catch (\Exception $e) {
// Multisite not enabled in the DB
}
if (!isset($blogs) || !$blogs || (is_array($blogs) && count($blogs) === 0)) {
$blogs = [['blog_id' => 1]];
}
$urlFuncMap = [
'home' => 'get_home_url',
'siteurl' => 'get_site_url'
];
foreach ($blogs as $blog) {
$blogId = (int)$blog['blog_id'];
$key = 'blog_' . $blogId;
$prefix = $blogId === 1 ? $wpdb->prefix : $wpdb->prefix . $blogId . '_';
$data['blogs'][$key] = $blog;
// Get URLs via functions
// This gives plugins a chance to change values
foreach ($urlFuncMap as $optionName => $func) {
$data['blogs'][$key][$optionName] = _try_catch_callback(function() use($func) { return $func(); });
$data['blogs'][$key]['option__' . $optionName] = _try_catch_callback(function() use ($wpdb, $prefix, $optionName) {
return $wpdb->get_var("SELECT option_value FROM {$prefix}options WHERE option_name = '{$optionName}' LIMIT 1");
});
}
}
return $data;
}
/**
*
*/
function _try_catch_callback(\Closure $callback)
{
try {
return $callback();
} catch (\Exception $e) {
return $e->getMessage();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment