Lines
96.66%
29 / 30
Methods
75.00%
3 / 4
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| fixIncludePath | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 2 | ||
| configurePcre | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| registerErrorHandlers | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| configureSession | 95.65% | 22 / 23 | 0.00% | 0 / 1 | 7 | ||
| 26 | class PhpConfigurator | |
| 27 | { | |
| 28 | /** @var null|callable(string): void */ | |
| 29 | private static $redisConfigurator = [RedisSessionHandler::class, 'configure']; | |
| 30 | ||
| 31 | /** | |
| 32 | * Ensures '.' is in the PHP include path. | |
| 33 | */ | |
| 34 | public static function fixIncludePath(): void | |
| 35 | { | |
| 36 | $includePaths = explode(PATH_SEPARATOR, (string) ini_get('include_path')); | |
| 37 | if (!in_array('.', $includePaths, strict: true)) { | |
| 38 | set_include_path('.' . PATH_SEPARATOR . (string) get_include_path()); | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | /** | |
| 43 | * Increases PCRE limits to handle large content. | |
| 44 | */ | |
| 45 | /* @mago-expect lint:no-ini-set - this bootstrap class is the single place that configures PHP runtime settings */ | |
| 46 | public static function configurePcre(): void | |
| 47 | { | |
| 48 | ini_set('pcre.backtrack_limit', value: '100000000'); | |
| 49 | ini_set('pcre.recursion_limit', value: '100000000'); | |
| 50 | } | |
| 51 | ||
| 52 | /** | |
| 53 | * Registers the phpMyFAQ error and exception handlers. | |
| 54 | */ | |
| 55 | public static function registerErrorHandlers(): void | |
| 56 | { | |
| 57 | set_error_handler(\phpMyFAQ\Core\Error::errorHandler(...)); | |
| 58 | set_exception_handler(\phpMyFAQ\Core\Error::exceptionHandler(...)); | |
| 59 | } | |
| 60 | ||
| 61 | /** | |
| 62 | * Configures secure session settings if no session is active yet. | |
| 63 | */ | |
| 64 | /* @mago-expect lint:no-ini-set - this bootstrap class is the single place that configures PHP runtime settings */ | |
| 65 | public static function configureSession(?Configuration $configuration = null): void | |
| 66 | { | |
| 67 | if (session_status() !== PHP_SESSION_ACTIVE) { | |
| 68 | ini_set('session.use_only_cookies', value: '1'); | |
| 69 | ini_set('session.use_trans_sid', value: '0'); | |
| 70 | ini_set('session.cookie_samesite', value: 'Strict'); | |
| 71 | ini_set('session.cookie_httponly', value: '1'); | |
| 72 | ini_set('session.cookie_secure', value: '1'); | |
| 73 | ||
| 74 | $sessionSavePath = trim((string) ($configuration?->get('session.savePath') ?? '')); | |
| 75 | ||
| 76 | if ($sessionSavePath !== '') { | |
| 77 | ini_set('session.save_path', $sessionSavePath); | |
| 78 | } | |
| 79 | ||
| 80 | $sessionHandler = strtolower((string) ($configuration?->get('session.handler') ?? 'files')); | |
| 81 | $redisDsn = trim((string) ($configuration?->get('session.redisDsn') ?? '')); | |
| 82 | ||
| 83 | switch ($sessionHandler) { | |
| 84 | case 'files': | |
| 85 | ini_set('session.save_handler', value: 'files'); | |
| 86 | break; | |
| 87 | case 'redis': | |
| 88 | if (self::$redisConfigurator === null) { | |
| 89 | throw new RuntimeException('No Redis session configurator is registered.'); | |
| 90 | } | |
| 91 | ||
| 92 | call_user_func(self::$redisConfigurator, $redisDsn); | |
| 93 | break; | |
| 94 | default: | |
| 95 | throw new RuntimeException(sprintf( | |
| 96 | 'Unsupported session handler "%s". Allowed values: files, redis.', | |
| 97 | $sessionHandler, | |
| 98 | )); | |
| 99 | } | |
| 100 | } | |
| 101 | } | |
| 102 | } |