104 lines
2.9 KiB
PHP
104 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace OCA\Support\Sections;
|
|
|
|
use DOMDocument;
|
|
use DOMXPath;
|
|
use OCA\Support\IDetail;
|
|
use OCA\Support\Section;
|
|
|
|
class PhpInfoSection extends Section {
|
|
public function __construct(
|
|
) {
|
|
parent::__construct('phpinfo', 'Phpinfo');
|
|
}
|
|
|
|
#[\Override]
|
|
public function getDetails(): array {
|
|
ob_start();
|
|
phpinfo(INFO_CONFIGURATION | INFO_MODULES);
|
|
$phpinfo = ob_get_clean();
|
|
|
|
if ($phpinfo === false) {
|
|
$this->createDetail('error', 'Failed to retrieve phpinfo output.', IDetail::TYPE_SINGLE_LINE);
|
|
return parent::getDetails();
|
|
}
|
|
|
|
if (strpos($phpinfo, '<!DOCTYPE html>') === false) {
|
|
// If phpinfo output is not HTML, we dump the raw output
|
|
$this->createDetail('phpifo', $phpinfo, IDetail::TYPE_COLLAPSIBLE_PREFORMAT);
|
|
return parent::getDetails();
|
|
}
|
|
|
|
$parsedInfo = array_values($this->parsePhpInfoFromHtml($phpinfo))[0] ?? [];
|
|
foreach ($parsedInfo as $sectionName => $sectionData) {
|
|
$this->createDetail($sectionName, json_encode($sectionData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), IDetail::TYPE_COLLAPSIBLE_PREFORMAT);
|
|
}
|
|
|
|
return parent::getDetails();
|
|
}
|
|
|
|
private function parsePhpInfoFromHtml(string $phpInfoHtmlStr): array {
|
|
$dom = new DOMDocument();
|
|
libxml_use_internal_errors(true);
|
|
$dom->loadHTML($phpInfoHtmlStr, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
|
libxml_clear_errors();
|
|
|
|
$xpath = new DOMXPath($dom);
|
|
|
|
$result = [];
|
|
$currentSection = '';
|
|
$currentSubsection = '';
|
|
|
|
$elements = $xpath->query('//h1 | //h2 | //table');
|
|
|
|
foreach ($elements as $el) {
|
|
if ($el->nodeName === 'h1') {
|
|
$currentSection = trim($el->textContent);
|
|
$result[$currentSection] = [];
|
|
} elseif ($el->nodeName === 'h2') {
|
|
$currentSubsection = trim($el->textContent);
|
|
if (!isset($result[$currentSection][$currentSubsection])) {
|
|
$result[$currentSection][$currentSubsection] = [];
|
|
}
|
|
} elseif ($el->nodeName === 'table') {
|
|
$rows = $el->getElementsByTagName('tr');
|
|
|
|
foreach ($rows as $row) {
|
|
$cols = $row->getElementsByTagName('td');
|
|
$ths = $row->getElementsByTagName('th');
|
|
|
|
if ($cols->length === 2) {
|
|
// Single key => value
|
|
$key = trim($cols->item(0)->textContent);
|
|
$val = trim($cols->item(1)->textContent);
|
|
$result[$currentSection][$currentSubsection][$key] = $val;
|
|
} elseif ($cols->length === 3) {
|
|
// Directive with local/master value
|
|
$key = trim($cols->item(0)->textContent);
|
|
$local = trim($cols->item(1)->textContent);
|
|
$master = trim($cols->item(2)->textContent);
|
|
$result[$currentSection][$currentSubsection][$key] = [
|
|
'local' => $local,
|
|
'master' => $master,
|
|
];
|
|
} elseif ($ths->length > 0) {
|
|
// This is a header row; skip or save metadata
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
}
|