Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
61.90% covered (warning)
61.90%
26 / 42
50.00% covered (danger)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ModuleLoggerInitializer
61.90% covered (warning)
61.90%
26 / 42
50.00% covered (danger)
50.00%
3 / 6
63.37
0.00% covered (danger)
0.00%
0 / 1
 configure
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
11
 initializeCache
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
4.68
 tryInitializeCache
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getRequestLimits
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 registerHttpMiddleware
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 validateCacheDirectory
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
6.60
1<?php
2
3declare(strict_types=1);
4
5namespace BO\Slim\Helper;
6
7use BO\Slim\LoggerService;
8use BO\Slim\Middleware\RequestLoggingMiddleware;
9use BO\Slim\Middleware\RequestSanitizerMiddleware;
10use BO\Slim\Middleware\SecurityHeadersMiddleware;
11use Psr\SimpleCache\CacheInterface;
12use Symfony\Component\Cache\Adapter\FilesystemAdapter;
13use Symfony\Component\Cache\Psr16Cache;
14
15final class ModuleLoggerInitializer
16{
17    /**
18     * @SuppressWarnings(PHPMD.NPathComplexity)
19     */
20    public static function configure(string $envPrefix): void
21    {
22        LoggerService::configure([
23            'maxRequests' => (int) (getenv("{$envPrefix}_LOGGER_MAX_REQUESTS") ?: 1000),
24            'maxErrorRequests' => (int) (getenv("{$envPrefix}_LOGGER_MAX_ERROR_REQUESTS") ?: 0),
25            'responseLength' => (int) (getenv("{$envPrefix}_LOGGER_RESPONSE_LENGTH") ?: 1048576),
26            'stackLines' => (int) (getenv("{$envPrefix}_LOGGER_STACK_LINES") ?: 20),
27            'messageSize' => (int) (getenv("{$envPrefix}_LOGGER_MESSAGE_SIZE") ?: 8192),
28            'cacheTtl' => (int) (getenv("{$envPrefix}_LOGGER_CACHE_TTL") ?: 60),
29            'maxRetries' => (int) (getenv("{$envPrefix}_LOGGER_MAX_RETRIES") ?: 3),
30            'backoffMin' => (int) (getenv("{$envPrefix}_LOGGER_BACKOFF_MIN") ?: 100),
31            'backoffMax' => (int) (getenv("{$envPrefix}_LOGGER_BACKOFF_MAX") ?: 1000),
32            'lockTimeout' => (int) (getenv("{$envPrefix}_LOGGER_LOCK_TIMEOUT") ?: 5),
33        ]);
34    }
35
36    public static function initializeCache(?string $cacheDir = null): CacheInterface
37    {
38        $cacheDir ??= getenv('CACHE_DIR') ?: sys_get_temp_dir();
39        $ttl = (int) (getenv('SOURCE_CACHE_TTL') ?: 3600);
40        self::validateCacheDirectory($cacheDir);
41
42        $psr6 = new FilesystemAdapter(namespace: '', defaultLifetime: $ttl, directory: $cacheDir);
43        $cache = new Psr16Cache($psr6);
44        LoggerService::$cache = $cache;
45
46        return $cache;
47    }
48
49    public static function tryInitializeCache(?string $cacheDir = null): ?CacheInterface
50    {
51        try {
52            return self::initializeCache($cacheDir);
53        } catch (\RuntimeException) {
54            LoggerService::$cache = null;
55
56            return null;
57        }
58    }
59
60    /**
61     * @return array{maxStringLength: int, maxRecursionDepth: int}
62     */
63    public static function getRequestLimits(): array
64    {
65        return [
66            'maxStringLength' => (int) (getenv('MAX_STRING_LENGTH') ?: 32768),
67            'maxRecursionDepth' => (int) (getenv('MAX_RECURSION_DEPTH') ?: 10),
68        ];
69    }
70
71    public static function registerHttpMiddleware(bool $includeSecurityHeaders = true): void
72    {
73        $logger = new LoggerService();
74        $requestLimits = self::getRequestLimits();
75
76        \App::$slim->add(new RequestLoggingMiddleware($logger));
77        if ($includeSecurityHeaders) {
78            \App::$slim->add(new SecurityHeadersMiddleware($logger));
79        }
80        \App::$slim->add(new RequestSanitizerMiddleware(
81            $logger,
82            $requestLimits['maxRecursionDepth'],
83            $requestLimits['maxStringLength']
84        ));
85    }
86
87    private static function validateCacheDirectory(string $cacheDir): void
88    {
89        if (!is_dir($cacheDir)) {
90            if (!@mkdir($cacheDir, 0750, true) && !is_dir($cacheDir)) {
91                throw new \RuntimeException(sprintf('Cache directory "%s" could not be created', $cacheDir));
92            }
93        }
94
95        if (!is_writable($cacheDir)) {
96            throw new \RuntimeException(sprintf('Cache directory "%s" is not writable', $cacheDir));
97        }
98    }
99}