Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
6.38% covered (danger)
6.38%
3 / 47
11.11% covered (danger)
11.11%
1 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Application
6.38% covered (danger)
6.38%
3 / 47
11.11% covered (danger)
11.11%
1 / 9
671.25
0.00% covered (danger)
0.00%
0 / 1
 getNow
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 initializeCache
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 initializeLogger
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
132
 initializeRequestLimits
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
12
 validateCacheDirectory
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 setupCache
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getLoggerConfig
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 getRequestLimits
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 initialize
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * @package 115Mandant
5 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
6 **/
7
8namespace BO\Zmsapi;
9
10use BO\Slim\LoggerService;
11use Psr\SimpleCache\CacheInterface;
12use Symfony\Component\Cache\Adapter\FilesystemAdapter;
13use Symfony\Component\Cache\Psr16Cache;
14
15if (($token = getenv('ZMS_CONFIG_SECURE_TOKEN')) === false || $token === '') {
16    throw new \RuntimeException('ZMS_CONFIG_SECURE_TOKEN environment variable must be set');
17}
18
19define('ZMS_CONFIG_SECURE_TOKEN', getenv('ZMS_CONFIG_SECURE_TOKEN'));
20
21if (!defined('ZMS_API_TWIG_CACHE')) {
22    $value = getenv('ZMS_API_TWIG_CACHE');
23    define('ZMS_API_TWIG_CACHE', ($value === 'false') ? false : ($value ?: '/cache/'));
24}
25
26class Application extends \BO\Slim\Application
27{
28    /**
29     * Name of the application
30     */
31    const IDENTIFIER = 'zms';
32
33    const MODULE_NAME = 'zmsapi';
34
35    public static ?CacheInterface $cache = null;
36    // Cache config
37    public static string $CACHE_DIR;
38    public static int $SOURCE_CACHE_TTL;
39    // Logger config
40    public static int $LOGGER_MAX_REQUESTS;
41    public static int $LOGGER_MAX_ERROR_REQUESTS;
42    public static int $LOGGER_RESPONSE_LENGTH;
43    public static int $LOGGER_STACK_LINES;
44    public static int $LOGGER_MESSAGE_SIZE;
45    public static int $LOGGER_CACHE_TTL;
46    public static int $LOGGER_MAX_RETRIES;
47    public static int $LOGGER_BACKOFF_MIN;
48    public static int $LOGGER_BACKOFF_MAX;
49    public static int $LOGGER_LOCK_TIMEOUT;
50    // Request sanitizer config
51    public static int $MAX_STRING_LENGTH;
52    public static int $MAX_RECURSION_DEPTH;
53
54    /**
55     * @var Bool DEBUG
56     */
57    const DEBUG = false;
58    const TWIG_CACHE = ZMS_API_TWIG_CACHE;
59
60    /**
61     * @var Bool DB_ENABLE_WSREPSYNCWAIT
62     */
63    const DB_ENABLE_WSREPSYNCWAIT = false;
64
65    /**
66     * @var Bool RIGHTSCHECK_ENABLED
67     */
68    const RIGHTSCHECK_ENABLED = true;
69
70    /**
71     * @var String DB_DSN_READONLY
72     */
73    const DB_DSN_READONLY = 'mysql:dbname=zmsbo;host=127.0.0.1';
74
75    /**
76     * @var String DB_DSN_READWRITE
77     */
78    const DB_DSN_READWRITE = 'mysql:dbname=zmsbo;host=127.0.0.1';
79
80    /**
81     * temporary db name for using dldb data
82     * @var String DB_STARTINFO
83     */
84    const DB_STARTINFO = 'startinfo';
85
86    /**
87     * @var String DB_USERNAME
88     */
89    const DB_USERNAME = 'server';
90
91    /**
92     * @var String DB_PASSWORD
93     */
94    const DB_PASSWORD = 'internet';
95
96    /**
97     * @var String DB_IS_GALERA
98     */
99    const DB_IS_GALERA = true;
100
101    /**
102     * @var String Security Token for Api Access -> get config for example
103     */
104    const SECURE_TOKEN = ZMS_CONFIG_SECURE_TOKEN;
105
106    /**
107     * language preferences
108     */
109
110    public static $locale = 'de';
111
112    public static $supportedLanguages = array(
113        // Default language
114        'de' => array(
115            'name'    => 'Deutsch',
116            'locale'  => 'de_DE.utf-8',
117            'default' => true,
118        )
119    );
120
121    /**
122     * dldb data path
123     */
124    public static $data = '/data';
125
126    /**
127     * @var \DateTimeInterface $now time to use for today (testing)
128     */
129    public static $now = null;
130
131    public static function getNow()
132    {
133        if (self::$now instanceof \DateTimeInterface) {
134            return self::$now;
135        }
136        return new \DateTimeImmutable();
137    }
138
139    private static function initializeCache(): void
140    {
141        self::$CACHE_DIR = getenv('CACHE_DIR') ?: __DIR__ . '/cache';
142        self::$SOURCE_CACHE_TTL = (int) (getenv('SOURCE_CACHE_TTL') ?: 3600);
143        self::validateCacheDirectory();
144        self::setupCache();
145    }
146
147    /**
148     * @SuppressWarnings(PHPMD.NPathComplexity)
149     * @TODO: Extract logger initialization logic into a dedicated LoggerInitializer class
150     */
151    private static function initializeLogger(): void
152    {
153        self::$LOGGER_MAX_REQUESTS = (int) (getenv('ZMS_API_LOGGER_MAX_REQUESTS') ?: 1000);
154        self::$LOGGER_MAX_ERROR_REQUESTS = (int) (getenv('ZMS_API_LOGGER_MAX_ERROR_REQUESTS') ?: 0);
155        self::$LOGGER_RESPONSE_LENGTH = (int) (getenv('ZMS_API_LOGGER_RESPONSE_LENGTH') ?: 1048576);
156        self::$LOGGER_STACK_LINES = (int) (getenv('ZMS_API_LOGGER_STACK_LINES') ?: 20);
157        self::$LOGGER_MESSAGE_SIZE = (int) (getenv('ZMS_API_LOGGER_MESSAGE_SIZE') ?: 8192);
158        self::$LOGGER_CACHE_TTL = (int) (getenv('ZMS_API_LOGGER_CACHE_TTL') ?: 60);
159        self::$LOGGER_MAX_RETRIES = (int) (getenv('ZMS_API_LOGGER_MAX_RETRIES') ?: 3);
160        self::$LOGGER_BACKOFF_MIN = (int) (getenv('ZMS_API_LOGGER_BACKOFF_MIN') ?: 100);
161        self::$LOGGER_BACKOFF_MAX = (int) (getenv('ZMS_API_LOGGER_BACKOFF_MAX') ?: 1000);
162        self::$LOGGER_LOCK_TIMEOUT = (int) (getenv('ZMS_API_LOGGER_LOCK_TIMEOUT') ?: 5);
163        LoggerService::configure(self::getLoggerConfig());
164    }
165
166    private static function initializeRequestLimits(): void
167    {
168        self::$MAX_STRING_LENGTH = (int) (getenv('MAX_STRING_LENGTH') ?: 32768);
169        self::$MAX_RECURSION_DEPTH = (int) (getenv('MAX_RECURSION_DEPTH') ?: 10);
170    }
171
172    private static function validateCacheDirectory(): void
173    {
174        if (!is_dir(self::$CACHE_DIR)) {
175            if (!@mkdir(self::$CACHE_DIR, 0750, true) && !is_dir(self::$CACHE_DIR)) {
176                throw new \RuntimeException(sprintf('Cache directory "%s" could not be created', self::$CACHE_DIR));
177            }
178        }
179
180        if (!is_writable(self::$CACHE_DIR)) {
181            throw new \RuntimeException(sprintf('Cache directory "%s" is not writable', self::$CACHE_DIR));
182        }
183    }
184
185    private static function setupCache(): void
186    {
187        $psr6 = new FilesystemAdapter(namespace: '', defaultLifetime: self::$SOURCE_CACHE_TTL, directory: self::$CACHE_DIR);
188        self::$cache = new Psr16Cache($psr6);
189        LoggerService::$cache = self::$cache;
190    }
191
192    public static function getLoggerConfig(): array
193    {
194        return [
195            'maxRequests' => self::$LOGGER_MAX_REQUESTS,
196            'maxErrorRequests' => self::$LOGGER_MAX_ERROR_REQUESTS,
197            'responseLength' => self::$LOGGER_RESPONSE_LENGTH,
198            'stackLines' => self::$LOGGER_STACK_LINES,
199            'messageSize' => self::$LOGGER_MESSAGE_SIZE,
200            'cacheTtl' => self::$LOGGER_CACHE_TTL,
201            'maxRetries' => self::$LOGGER_MAX_RETRIES,
202            'backoffMin' => self::$LOGGER_BACKOFF_MIN,
203            'backoffMax' => self::$LOGGER_BACKOFF_MAX,
204            'lockTimeout' => self::$LOGGER_LOCK_TIMEOUT,
205        ];
206    }
207
208    public static function getRequestLimits(): array
209    {
210        return [
211            'maxStringLength' => self::$MAX_STRING_LENGTH,
212            'maxRecursionDepth' => self::$MAX_RECURSION_DEPTH,
213        ];
214    }
215
216    public static function initialize(): void
217    {
218        self::initializeLogger();
219        self::initializeCache();
220        self::initializeRequestLimits();
221    }
222}
223
224Application::initialize();