<?php
declare(strict_types=1);

/**
 * opcache_status.php - standalone OPcache diagnostic.
 *
 * Drop this in your CMSB folder and open it in a browser:
 *     https://yoursite.com/cmsb/opcache_status.php
 *
 * It reports whether OPcache is actually loaded and enabled under the SAME
 * PHP/SAPI that serves CMSB. That tells you if the problem is your php.ini
 * (opcache not loading on the web SAPI) rather than anything in the CMS.
 *
 * It runs standalone and does NOT include CMSB, so PHP startup warnings show
 * here in plain text instead of corrupting a JSON response.
 *
 * Delete this file when you're done - it exposes server config paths.
 */

header('Content-Type: text/html; charset=utf-8');

$h = fn(?string $v): string => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');

// Detect state from ini_get(), which is never restricted. The opcache.* settings
// are registered by the extension, so if opcache.so fails to load they read as off.
$extLoaded  = extension_loaded('Zend OPcache');
$iniEnabled = ini_get('opcache.enable') === '1';
$cacheOnly  = ini_get('opcache.file_cache_only') === '1';

// one-line verdict
[$verdictTag, $verdictMsg] = match (true) {
    !$extLoaded  => ['FAIL', 'OPcache extension is NOT loaded on this SAPI. Your zend_extension line is failing here.'],
    !$iniEnabled => ['FAIL', 'OPcache is loaded but not enabled (opcache.enable is off for this SAPI).'],
    $cacheOnly   => ['OK',   'OPcache is loaded and running in file-cache-only mode.'],
    default      => ['OK',   'OPcache is loaded and enabled.'],
};

// does opcache.so actually exist where PHP looks for it?
$extDir   = (string) ini_get('extension_dir');
$soPath   = rtrim($extDir, '/\\') . '/opcache.so';
$soExists = $extDir !== '' && is_file($soPath);

// file_cache directory health
$fileCacheDir = (string) ini_get('opcache.file_cache');
$fileCacheRow = match (true) {
    $fileCacheDir === ''        => 'not set',
    !is_dir($fileCacheDir)      => "MISSING - directory does not exist: $fileCacheDir",
    !is_writable($fileCacheDir) => "NOT WRITABLE by web user: $fileCacheDir",
    default                     => "ok, exists and writable: $fileCacheDir",
};

// environment rows
$envRows = [
    'PHP version'              => PHP_VERSION,
    'SAPI (how PHP runs here)' => PHP_SAPI,
    'Loaded php.ini'           => php_ini_loaded_file() ?: '(none)',
    'Extra .ini files scanned' => php_ini_scanned_files() ?: '(none)',
    'extension_dir'            => $extDir,
    'opcache.so present there' => $soExists ? "yes ($soPath)" : "NO - not found at $soPath",
];

// only the settings that matter for "is it loading and will file_cache work"
$iniRows = [
    'opcache.enable'          => ini_get('opcache.enable'),
    'opcache.file_cache'      => ini_get('opcache.file_cache'),
    'opcache.file_cache_only' => ini_get('opcache.file_cache_only'),
];

$tagColor = match ($verdictTag) {
    'OK'    => '#1a7f37',
    default => '#cf222e',
};

?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>OPcache status</title>
    <style>
        body  { font: 14px/1.5 -apple-system, Segoe UI, Roboto, sans-serif; max-width: 820px; margin: 30px auto; padding: 0 16px; color: #1f2328; }
        h1    { font-size: 20px; }
        h2    { font-size: 15px; margin-top: 28px; border-bottom: 1px solid #d0d7de; padding-bottom: 4px; }
        .tag  { display: inline-block; color: #fff; padding: 2px 10px; border-radius: 4px; font-weight: 600; }
        table { border-collapse: collapse; width: 100%; margin-top: 8px; }
        td    { border: 1px solid #d0d7de; padding: 6px 10px; vertical-align: top; }
        td:first-child { width: 240px; color: #57606a; white-space: nowrap; }
        code  { background: #eaeef2; padding: 1px 5px; border-radius: 4px; }
        .note { color: #57606a; font-size: 13px; margin-top: 24px; }
    </style>
</head>
<body>
    <h1>OPcache status (this PHP / SAPI)</h1>
    <p><span class="tag" style="background: <?= $h($tagColor) ?>"><?= $h($verdictTag) ?></span> <?= $h($verdictMsg) ?></p>

    <h2>Environment</h2>
    <table>
        <?php foreach ($envRows as $label => $value) { ?>
            <tr><td><?= $h($label) ?></td><td><code><?= $h($value) ?></code></td></tr>
        <?php } ?>
    </table>

    <h2>OPcache settings</h2>
    <table>
        <?php foreach ($iniRows as $key => $value) { ?>
            <tr><td><?= $h($key) ?></td><td><code><?= $h($value === false ? '(undefined)' : (string) $value) ?></code></td></tr>
        <?php } ?>
        <tr><td>file_cache directory</td><td><?= $h($fileCacheRow) ?></td></tr>
    </table>

</body>
</html>
