137 lines
4.3 KiB
PHP
137 lines
4.3 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
final class InstallationService
|
||
{
|
||
public static function runtimeChecks(bool $withFilesystem = true): array
|
||
{
|
||
$checks = [];
|
||
self::add($checks, 'php', version_compare(PHP_VERSION, '8.1.0', '>='), 'required', 'PHP 8.1+', PHP_VERSION);
|
||
self::add(
|
||
$checks,
|
||
'pdo',
|
||
extension_loaded('pdo'),
|
||
'required',
|
||
'PDO',
|
||
extension_loaded('pdo') ? 'Disponible' : 'Extension absente',
|
||
);
|
||
self::add(
|
||
$checks,
|
||
'sqlite',
|
||
extension_loaded('pdo_sqlite'),
|
||
'required',
|
||
'PDO SQLite',
|
||
extension_loaded('pdo_sqlite') ? 'Disponible' : 'Installez l’extension PHP SQLite',
|
||
);
|
||
foreach (
|
||
['mbstring' => 'mbstring', 'json' => 'JSON', 'fileinfo' => 'Fileinfo', 'session' => 'Sessions']
|
||
as $extension => $label
|
||
) {
|
||
self::add(
|
||
$checks,
|
||
$extension,
|
||
extension_loaded($extension),
|
||
'required',
|
||
$label,
|
||
extension_loaded($extension) ? 'Disponible' : 'Extension absente',
|
||
);
|
||
}
|
||
self::add(
|
||
$checks,
|
||
'zip',
|
||
class_exists('ZipArchive'),
|
||
'recommended',
|
||
'ZIP',
|
||
class_exists('ZipArchive')
|
||
? 'Sauvegardes ZIP disponibles'
|
||
: 'Extension ZIP absente : sauvegardes indisponibles',
|
||
);
|
||
self::add(
|
||
$checks,
|
||
'curl',
|
||
extension_loaded('curl'),
|
||
'recommended',
|
||
'cURL',
|
||
extension_loaded('curl')
|
||
? 'Connecteurs externes disponibles'
|
||
: 'Extension cURL absente : I-CAD et géocodage indisponibles',
|
||
);
|
||
self::add(
|
||
$checks,
|
||
'image',
|
||
extension_loaded('imagick') || extension_loaded('gd'),
|
||
'recommended',
|
||
'Traitement des images',
|
||
extension_loaded('imagick')
|
||
? 'ImageMagick disponible'
|
||
: (extension_loaded('gd')
|
||
? 'GD disponible'
|
||
: 'ImageMagick ou GD conseillé'),
|
||
);
|
||
if ($withFilesystem) {
|
||
foreach (self::directories() as $key => $path) {
|
||
if (!is_dir($path)) {
|
||
@mkdir($path, 0775, true);
|
||
}
|
||
self::add(
|
||
$checks,
|
||
'dir_' . $key,
|
||
is_dir($path) && is_writable($path),
|
||
'required',
|
||
'Écriture · ' . self::relative($path),
|
||
is_dir($path) && is_writable($path) ? 'Accessible en écriture' : 'Droits d’écriture insuffisants',
|
||
);
|
||
}
|
||
}
|
||
return $checks;
|
||
}
|
||
public static function blockingRuntimeIssues(): array
|
||
{
|
||
return array_values(
|
||
array_filter(
|
||
self::runtimeChecks(true),
|
||
static fn(array $c): bool => $c['level'] === 'required' && !$c['ok'],
|
||
),
|
||
);
|
||
}
|
||
public static function canInstall(array $checks): bool
|
||
{
|
||
foreach ($checks as $check) {
|
||
if ($check['level'] === 'required' && !$check['ok']) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
public static function publicPath(): string
|
||
{
|
||
return dirname(__DIR__, 2) . '/public';
|
||
}
|
||
public static function directories(): array
|
||
{
|
||
$root = dirname(__DIR__, 2);
|
||
return [
|
||
'data' => $root . '/data',
|
||
'storage' => $root . '/storage',
|
||
'logs' => $root . '/storage/logs',
|
||
'backups' => $root . '/storage/backups',
|
||
'media' => $root . '/public/media',
|
||
'association' => $root . '/data/association',
|
||
];
|
||
}
|
||
private static function add(
|
||
array &$checks,
|
||
string $key,
|
||
bool $ok,
|
||
string $level,
|
||
string $label,
|
||
string $detail,
|
||
): void {
|
||
$checks[] = ['key' => $key, 'ok' => $ok, 'level' => $level, 'label' => $label, 'detail' => $detail];
|
||
}
|
||
private static function relative(string $path): string
|
||
{
|
||
return ltrim(str_replace(dirname(__DIR__, 2), '', $path), '/');
|
||
}
|
||
}
|