2023-10-12 15:04:11 +00:00
< ? php
declare ( strict_types = 1 );
/**
2024-06-03 08:23:34 +00:00
* SPDX - FileCopyrightText : 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX - License - Identifier : AGPL - 3.0 - or - later
2023-10-12 15:04:11 +00:00
*/
namespace OCA\Settings\SetupChecks ;
use OCP\IL10N ;
2023-10-26 14:16:39 +00:00
use OCP\IURLGenerator ;
2023-10-12 15:04:11 +00:00
use OCP\SetupCheck\ISetupCheck ;
use OCP\SetupCheck\SetupResult ;
class PhpModules implements ISetupCheck {
protected const REQUIRED_MODULES = [
'ctype' ,
'curl' ,
'dom' ,
'fileinfo' ,
'gd' ,
'json' ,
'mbstring' ,
'openssl' ,
'posix' ,
'session' ,
'xml' ,
'xmlreader' ,
'xmlwriter' ,
'zip' ,
'zlib' ,
];
protected const RECOMMENDED_MODULES = [
2024-01-22 14:08:59 +00:00
'bcmath' ,
2023-10-12 15:04:11 +00:00
'exif' ,
2024-01-22 14:08:59 +00:00
'gmp' ,
2024-01-15 23:34:23 +00:00
'intl' ,
2023-10-12 15:04:11 +00:00
'sodium' ,
2024-01-15 23:34:23 +00:00
'sysvsem' ,
2023-10-12 15:04:11 +00:00
];
public function __construct (
private IL10N $l10n ,
2023-10-26 14:16:39 +00:00
private IURLGenerator $urlGenerator ,
2023-10-12 15:04:11 +00:00
) {
}
public function getName () : string {
return $this -> l10n -> t ( 'PHP modules' );
}
public function getCategory () : string {
2024-01-15 16:08:14 +00:00
return 'php' ;
2023-10-12 15:04:11 +00:00
}
2024-01-16 09:03:22 +00:00
protected function getRecommendedModuleDescription ( string $module ) : string {
return match ( $module ) {
'intl' => $this -> l10n -> t ( 'increases language translation performance and fixes sorting of non-ASCII characters' ),
'sodium' => $this -> l10n -> t ( 'for Argon2 for password hashing' ),
'bcmath' => $this -> l10n -> t ( 'for WebAuthn passwordless login' ),
'gmp' => $this -> l10n -> t ( 'for WebAuthn passwordless login, and SFTP storage' ),
2024-01-18 13:57:13 +00:00
'exif' => $this -> l10n -> t ( 'for picture rotation in server and metadata extraction in the Photos app' ),
2024-01-16 09:03:22 +00:00
default => '' ,
};
}
2023-10-12 15:04:11 +00:00
public function run () : SetupResult {
$missingRecommendedModules = $this -> getMissingModules ( self :: RECOMMENDED_MODULES );
$missingRequiredModules = $this -> getMissingModules ( self :: REQUIRED_MODULES );
if ( ! empty ( $missingRequiredModules )) {
2023-10-26 14:16:39 +00:00
return SetupResult :: error (
2023-11-07 13:14:36 +00:00
$this -> l10n -> t ( 'This instance is missing some required PHP modules. It is required to install them: %s.' , implode ( ', ' , $missingRequiredModules )),
2023-10-26 14:16:39 +00:00
$this -> urlGenerator -> linkToDocs ( 'admin-php-modules' )
);
2023-10-12 15:04:11 +00:00
} elseif ( ! empty ( $missingRecommendedModules )) {
2024-01-16 09:03:22 +00:00
$moduleList = implode (
" \n " ,
array_map (
fn ( string $module ) => '- ' . $module . ' ' . $this -> getRecommendedModuleDescription ( $module ),
$missingRecommendedModules
)
);
2023-10-26 14:16:39 +00:00
return SetupResult :: info (
2024-01-16 09:03:22 +00:00
$this -> l10n -> t ( " This instance is missing some recommended PHP modules. For improved performance and better compatibility it is highly recommended to install them: \n %s " , $moduleList ),
2023-10-26 14:16:39 +00:00
$this -> urlGenerator -> linkToDocs ( 'admin-php-modules' )
);
2023-10-12 15:04:11 +00:00
} else {
return SetupResult :: success ();
}
}
/**
* Checks for potential PHP modules that would improve the instance
*
* @ param string [] $modules modules to test
* @ return string [] A list of PHP modules which are missing
*/
protected function getMissingModules ( array $modules ) : array {
return array_values ( array_filter (
$modules ,
fn ( string $module ) => ! extension_loaded ( $module ),
));
}
}