Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
117 / 117
100.00% covered (success)
100.00%
14 / 14
CRAP
100.00% covered (success)
100.00%
1 / 1
Defaults
100.00% covered (success)
100.00%
117 / 117
100.00% covered (success)
100.00%
14 / 14
14
100.00% covered (success)
100.00%
1 / 1
 values
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 app
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 auth
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 paths
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 panel
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 error
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 icons
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 database
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 session
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 media
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 richtext
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 upload
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
1
 uid
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 password
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Config;
6
7use Cosray\Uid as UidGenerator;
8use Cosray\Util\Password;
9
10use function Cosray\env;
11
12final class Defaults
13{
14    /** @return array<string, mixed> */
15    public static function values(string $root, Env $env): array
16    {
17        return array_merge(
18            self::app($env),
19            self::auth($env),
20            self::paths($root),
21            self::panel(),
22            self::error(),
23            self::icons(),
24            self::database(),
25            self::session($env),
26            self::media(),
27            self::richtext(),
28            self::upload(),
29            self::uid(),
30            self::password(),
31        );
32    }
33
34    /** @return array<string, mixed> */
35    private static function app(Env $env): array
36    {
37        return [
38            'app.name' => env('APP_NAME', 'cosray'),
39            'app.debug' => $env->bool('APP_DEBUG', false),
40            'app.env' => env('APP_ENV', ''),
41            'app.secret' => env('APP_SECRET', null),
42            'app.timezone' => env('APP_TIMEZONE', 'UTC'),
43            'plugins' => [],
44        ];
45    }
46
47    /** @return array<string, mixed> */
48    private static function auth(Env $env): array
49    {
50        return [
51            'auth.remember_lifetime' => $env->int('AUTH_REMEMBER_LIFETIME', 60 * 60 * 24 * 30),
52        ];
53    }
54
55    /** @return array<string, mixed> */
56    private static function paths(string $root): array
57    {
58        return [
59            'path.root' => $root,
60            'path.public' => $root . '/public',
61            'path.prefix' => '',
62            'path.assets' => '/assets',
63            'path.cache' => '/cache',
64            'path.views' => '/views',
65            'path.panel' => '/cp',
66            // The built panel client, served by the panel's own static route
67            // rather than by the web server. Keeping it out of the public
68            // directory means nothing occupies `{path.panel}` on disk, which
69            // would otherwise shadow the panel route itself.
70            'path.panelAssets' => $root . '/panel/static',
71        ];
72    }
73
74    /** @return array<string, mixed> */
75    private static function panel(): array
76    {
77        return [
78            'panel.theme' => [],
79            'panel.logo' => '/images/logo.png',
80            // Default panel UI language; NULL negotiates from the browser.
81            'panel.locale' => null,
82        ];
83    }
84
85    /** @return array<string, mixed> */
86    private static function error(): array
87    {
88        return [
89            'error.enabled' => true,
90            'error.renderer' => null,
91            'error.trusted' => [],
92            'error.views' => null,
93            'error.whoops' => true,
94        ];
95    }
96
97    /** @return array<string, mixed> */
98    private static function icons(): array
99    {
100        return [
101            'icons.local.paths' => [],
102            'icons.iconify.base_url' => 'https://api.iconify.design',
103            'icons.iconify.timeout' => 5,
104            'icons.iconify.user_agent' => 'cosray/cms',
105        ];
106    }
107
108    /** @return array<string, mixed> */
109    private static function database(): array
110    {
111        return [
112            'db.dsn' => env('DATABASE_URL', null),
113            'db.sql' => [],
114            'db.migrations' => [],
115            'db.placeholders' => [
116                'all' => [
117                    'cms.prefix' => 'cms_',
118                ],
119                'pgsql' => [
120                    'cms.prefix' => 'cms.',
121                ],
122            ],
123            'db.print' => false,
124            'db.options' => [],
125        ];
126    }
127
128    /** @return array<string, mixed> */
129    private static function session(Env $env): array
130    {
131        return [
132            'session.enabled' => $env->bool('SITE_SESSION_ENABLED', false),
133            'session.options' => [
134                'cookie_httponly' => true,
135                'cookie_samesite' => 'Lax',
136                'cookie_secure' => $env->bool('SESSION_COOKIE_SECURE', true),
137                'cookie_lifetime' => $env->int('SESSION_COOKIE_LIFETIME', 0),
138                'gc_maxlifetime' => $env->int('SESSION_IDLE_TIMEOUT', 60 * 60 * 8),
139                'cache_expire' => 3600,
140            ],
141            'session.handler' => null,
142        ];
143    }
144
145    /** @return array<string, mixed> */
146    private static function media(): array
147    {
148        return [
149            'media.fileserver' => null,
150            'media.sizes' => [],
151        ];
152    }
153
154    /** @return array<string, mixed> */
155    private static function richtext(): array
156    {
157        return [
158            'richtext.classes' => [],
159            'richtext.styles' => [],
160            'richtext.tools' => [],
161        ];
162    }
163
164    /** @return array<string, mixed> */
165    private static function upload(): array
166    {
167        return [
168            'upload.mimetypes.file' => [
169                'application/pdf' => ['pdf'],
170            ],
171            'upload.mimetypes.image' => [
172                'image/avif' => ['avif'],
173                'image/gif' => ['gif'],
174                'image/jpeg' => ['jpeg', 'jpg', 'jpe', 'jfif'],
175                'image/png' => ['png'],
176                'image/svg+xml' => ['svg'],
177                'image/webp' => ['webp'],
178            ],
179            'upload.mimetypes.video' => [
180                'video/mp4' => ['mp4', 'm4v'],
181                'video/ogg' => ['ogv', 'ogg'],
182                'video/webm' => ['webm'],
183            ],
184            'upload.maxsize' => 10 * 1024 * 1024,
185        ];
186    }
187
188    /** @return array<string, mixed> */
189    private static function uid(): array
190    {
191        return [
192            'uid.alphabet' => UidGenerator::ALPHABET_LOWERCASE_WORD_SAFE,
193            'uid.length' => 13,
194        ];
195    }
196
197    /** @return array<string, mixed> */
198    private static function password(): array
199    {
200        return [
201            'password.entropy' => Password::DEFAULT_PASSWORD_ENTROPY,
202            'password.algorithm' => null,
203        ];
204    }
205}