How to Configure the PHP Connector wpinspect.php

The PHP connector does not require any configuration by default, and any modifications to it are discouraged. However, if your WordPress is not located in the root directory of your domain, you will need to adjust the PHP connector wpinspect.php.

define('WPII_DEFAULT_PATH', '/');

This is the default setting. It specifies that WordPress is in the same directory as the PHP connector. The PHP connector must always remain in the root directory of the domain. If WordPress is installed in a different directory, you need to specify the path to it.


If your WordPress is not located in the root directory of your domain, you need to modify the following line in wpinspect.php:

define('WPII_DEFAULT_PATH', '/');

For example, if your WordPress is installed in a directory named web, update the line as follows:

define('WPII_DEFAULT_PATH', '/web/');


WP Integrity Inspector PHP Connector

This script facilitates communication between the WP Integrity Inspector tool and a WordPress website. It validates input, retrieves file information, computes file hashes, and provides database metadata. Ensure this script is placed in the root directory of your domain and configured correctly to work with your WordPress installation.



/**
*
* WP Integrity Inspector
* Generated on www.wpii.dev
*
* INSTRUCTION:
* 1. Save this file [wpinspect.php] to the ROOT directory of your domain [example.com]
* 2. Download and install the WP Integrity Inspector application from www.wpii.dev/download/
* 3. Run the WP Integrity Inspector application and add the site "[example.com]" using the password "[password]"
*
* NOTICE: If your WordPress installation IS NOT IN THE ROOT of the domain, set the correct path to WordPress in the WPII_DEFAULT_PATH definition:
*/

define('WPII_DEFAULT_PATH', '/');

/**
 *
 WARNING: Do not modify the source code:
 *
 */

// Configuration
define('WPII_PASSWORD', '[password]'); // Replace with your secure password
define('WPII_HASH', '[hash]');         // Replace with your unique hash

// Set response header to JSON
header('Content-Type: application/json');

// Read and decode input data
$inputData = json_decode(file_get_contents('php://input'), true);

// Validate input data
if (!is_array($inputData) || !isset($inputData['password'])) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'Invalid input data. Password is required.']);
    exit;
}

// Validate password
if ($inputData['password'] !== WPII_PASSWORD) {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'Invalid password']);
    exit;
}

// Confirm if 'files' key is present in input
if (!isset($inputData['files'])) {
    echo json_encode(['status' => 'success', 'message' => 'Password verified successfully']);
    exit;
}

// Resolve base path for file operations
$basePath = realpath(__DIR__ . DIRECTORY_SEPARATOR . ltrim(WPII_DEFAULT_PATH, '/'));
if ($basePath === false || !is_dir($basePath)) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => "Invalid base path: " . __DIR__ . DIRECTORY_SEPARATOR . WPII_DEFAULT_PATH]);
    exit;
}

/**
 * Recursively checks all PHP files in a given directory.
 *
 * @param string $dir Directory path to scan.
 * @return array List of PHP files with their relative paths.
 */
function checkAllFiles($dir)
{
    if (empty($dir) || !is_dir($dir)) {
        throw new InvalidArgumentException("The directory path is invalid or empty.");
    }

    $phpFiles = [];
    $items = scandir($dir);

    foreach ($items as $item) {
        if ($item === '.' || $item === '..') {
            continue;
        }

        $path = $dir . DIRECTORY_SEPARATOR . $item;

        if (is_dir($path)) {
            // Recursive scan for subdirectories
            try {
                $phpFiles = array_merge($phpFiles, checkAllFiles($path));
            } catch (Exception $e) {
                error_log("Unable to access directory: $path. Error: " . $e->getMessage());
            }
        } elseif (pathinfo($path, PATHINFO_EXTENSION) === 'php') {
            global $basePath;
            $relativePath = str_replace($basePath . DIRECTORY_SEPARATOR, '', $path);
            $phpFiles[] = ["File" => $relativePath];
        }
    }

    return $phpFiles;
}

// WordPress-specific checks
$wpLoadPath = $basePath . DIRECTORY_SEPARATOR . 'wp-load.php';
$wordpressAvailable = file_exists($wpLoadPath);
if ($wordpressAvailable) {
    require_once $wpLoadPath;
}

// Process requested files
$fileResults = [];
$fileHashes = [];
foreach ($inputData['files'] as $fileEntry) {
    $file = $fileEntry['File'] ?? null;

    if ($file) {
        $fullPath = $basePath . DIRECTORY_SEPARATOR . $file;

        if (file_exists($fullPath)) {
            $fileResults[$file] = [
                'exists' => true,
                'size' => filesize($fullPath),
                'last_modified' => date('Y-m-d H:i:s', filemtime($fullPath)),
            ];
            $fileHashes[$file] = [
                'hash_md5' => md5_file($fullPath),
                'hash_sha256' => hash_file('sha256', $fullPath),
            ];
        } else {
            $fileResults[$file] = ['exists' => false];
            $fileHashes[$file] = ['exists' => false];
        }
    }
}

// Fetch all PHP files
$allFiles = checkAllFiles($basePath);

// Add hashes for all files
foreach ($allFiles as $fileEntry) {
    $relativePath = $fileEntry['File'];
    $fullPath = $basePath . DIRECTORY_SEPARATOR . $relativePath;

    if (file_exists($fullPath)) {
        $fileResults[$relativePath] = [
            'exists' => true,
            'size' => filesize($fullPath),
            'last_modified' => date('Y-m-d H:i:s', filemtime($fullPath)),
        ];
        $fileHashes[$relativePath] = [
            'hash_md5' => md5_file($fullPath),
            'hash_sha256' => hash_file('sha256', $fullPath),
        ];
    }
}

// Database checks (if WordPress is available)
if (!$wordpressAvailable) {
    $dbResults = ['error' => 'WordPress environment not available'];
} elseif (isset($wpdb) && isset($wpdb->dbh) && mysqli_ping($wpdb->dbh)) {
    $dbResults = [];
    $tables = $wpdb->get_results("SHOW TABLE STATUS", ARRAY_A);

    foreach ($tables as $table) {
        $dbResults[] = [
            'table' => $table['Name'],
            'engine' => $table['Engine'] ?? 'Unknown',
            'rows' => $table['Rows'] ?? 0,
            'data_length' => $table['Data_length'] ?? 0,
            'index_length' => $table['Index_length'] ?? 0,
            'last_update' => $table['Update_time'] ?? 'Never',
        ];
    }
} else {
    $dbResults = ['error' => 'Database connection failed'];
}

// Build and send response
$response = [
    'header' => [
        'domain' => $_SERVER['HTTP_HOST'],
        'hash' => WPII_HASH,
        'timestamp' => date('Y-m-d H:i:s'),
    ],
    'body' => [
        'status' => 'success',
        'files' => $fileResults,
        'hashes' => $fileHashes,
        'database' => $dbResults,
    ],
];

echo json_encode($response);