Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
68 / 68
100.00% covered (success)
100.00%
22 / 22
CRAP
100.00% covered (success)
100.00%
1 / 1
App
100.00% covered (success)
100.00%
68 / 68
100.00% covered (success)
100.00%
22 / 22
52
100.00% covered (success)
100.00%
1 / 1
 set
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 has
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 config
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 router
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 services
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 events
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 modules
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 autoloader
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 url
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 env
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
10
 environment
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 middlewareDisabled
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 isLocal
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isDev
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isTesting
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isStaging
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isProduction
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 isDown
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isUp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isSecretRequest
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop;
16
17use Pop\Router\Router;
18
19/**
20 * Application helper class
21 *
22 * @category   Pop
23 * @package    Pop
24 * @author     Nick Sagona, III <nick@popphp.org>
25 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    5.0.0
28 */
29class App
30{
31
32    /**
33     * Application object
34     * @var ?Application
35     */
36    private static ?Application $application = null;
37
38    /**
39     * Set application object
40     *
41     * @param  Application $application
42     * @return void
43     */
44    public static function set(Application $application): void
45    {
46        self::$application = $application;
47    }
48
49    /**
50     * Get application object
51     *
52     * @return ?Application
53     */
54    public static function get(): ?Application
55    {
56        return self::$application;
57    }
58
59    /**
60     * Has application object
61     *
62     * @return bool
63     */
64    public static function has(): bool
65    {
66        return (self::$application !== null);
67    }
68
69    /**
70     * Get configuration
71     *
72     * @param  ?string $key
73     * @return mixed
74     */
75    public static function config(?string $key = null): mixed
76    {
77        if (self::$application !== null) {
78            if ($key !== null) {
79                return (isset(self::$application->config[$key])) ? self::$application->config[$key] : null;
80            } else {
81                return self::$application->config();
82            }
83        } else {
84            return null;
85        }
86    }
87
88    /**
89     * Get router
90     *
91     * @return ?Router
92     */
93    public static function router(): ?Router
94    {
95        return (self::$application !== null) ? self::$application->router() : null;
96    }
97
98    /**
99     * Get service locator
100     *
101     * @param  ?string $key
102     * @return mixed
103     */
104    public static function services(?string $key = null): mixed
105    {
106        if (self::$application !== null) {
107            if ($key !== null) {
108                return (isset(self::$application->services[$key])) ? self::$application->services[$key] : null;
109            } else {
110                return self::$application->services();
111            }
112        } else {
113            return null;
114        }
115    }
116
117    /**
118     * Get event manager
119     *
120     * @param  ?string $key
121     * @return mixed
122     */
123    public static function events(?string $key = null): mixed
124    {
125        if (self::$application !== null) {
126            if ($key !== null) {
127                return (isset(self::$application->events[$key])) ? self::$application->events[$key] : null;
128            } else {
129                return self::$application->events();
130            }
131        } else {
132            return null;
133        }
134    }
135
136    /**
137     * Get module manager
138     *
139     * @param  ?string $key
140     * @return mixed
141     */
142    public static function modules(?string $key = null): mixed
143    {
144        if (self::$application !== null) {
145            if ($key !== null) {
146                return (isset(self::$application->modules[$key])) ? self::$application->modules[$key] : null;
147            } else {
148                return self::$application->modules();
149            }
150        } else {
151            return null;
152        }
153    }
154
155    /**
156     * Get autoloader
157     *
158     * @return ?\Composer\Autoload\ClassLoader
159     */
160    public static function autoloader(): ?\Composer\Autoload\ClassLoader
161    {
162        return (self::$application !== null) ? self::$application->autoloader() : null;
163    }
164
165    /**
166     * Get application name
167     *
168     * @return ?string
169     */
170    public static function name(): ?string
171    {
172        return self::env('APP_NAME');
173    }
174
175    /**
176     * Get application URL
177     *
178     * @return ?string
179     */
180    public static function url(): ?string
181    {
182        return self::env('APP_URL');
183    }
184
185    /**
186     * Get environment value
187     *
188     * @param  string $key
189     * @param  mixed  $default
190     * @return mixed
191     */
192    public static function env(string $key, mixed $default = null): mixed
193    {
194        if (!isset($_ENV[$key])) {
195            return $default;
196        }
197
198        $value = $_ENV[$key];
199
200        switch ($value) {
201            case 'true':
202            case '(true)':
203                $value = true;
204                break;
205            case 'false':
206            case '(false)':
207                $value = false;
208                break;
209            case 'null':
210            case '(null)':
211                $value = null;
212                break;
213            case 'empty':
214            case '(empty)':
215                $value = '';
216                break;
217        }
218
219        return $value;
220    }
221
222    /**
223     * Get application environment
224     *
225     * @param  mixed $env
226     * @return string|null|bool
227     */
228    public static function environment(mixed $env = null): string|null|bool
229    {
230        if ($env === null) {
231            return self::env('APP_ENV');
232        }
233
234        if (!is_array($env)) {
235            $env = [$env];
236        }
237
238        return in_array(self::env('APP_ENV'), $env);
239    }
240
241    /**
242     * Get the normalized MIDDLEWARE_DISABLED value
243     *
244     * Guards two failure modes of comparing the raw env value directly: env()
245     * coercing a literal 'true' value into a real bool, which then loosely
246     * equals every non-empty string (silently matching 'route' as well as
247     * 'all'), and any value outside the recognized set ('all', 'route')
248     * otherwise being compared as-is instead of being treated as not set.
249     *
250     * @return string
251     */
252    public static function middlewareDisabled(): string
253    {
254        $value = self::env('MIDDLEWARE_DISABLED');
255
256        if ($value === true) {
257            return 'all';
258        }
259
260        return in_array($value, ['all', 'route'], true) ? $value : '';
261    }
262
263    /**
264     * Check if application environment is local
265     *
266     * @return bool
267     */
268    public static function isLocal(): bool
269    {
270        return (self::env('APP_ENV') == 'local');
271    }
272
273    /**
274     * Check if application environment is dev
275     *
276     * @return bool
277     */
278    public static function isDev(): bool
279    {
280        return (self::env('APP_ENV') == 'dev');
281    }
282
283    /**
284     * Check if application environment is testing
285     *
286     * @return bool
287     */
288    public static function isTesting(): bool
289    {
290        return (self::env('APP_ENV') == 'testing');
291    }
292
293    /**
294     * Check if application environment is staging
295     *
296     * @return bool
297     */
298    public static function isStaging(): bool
299    {
300        return (self::env('APP_ENV') == 'staging');
301    }
302
303    /**
304     * Check if application environment is production
305     *
306     * @return bool
307     */
308    public static function isProduction(): bool
309    {
310        return !empty(self::env('APP_ENV')) && str_starts_with(self::env('APP_ENV'), 'prod');
311    }
312
313    /**
314     * Check if application is in maintenance mode
315     *
316     * @return bool
317     */
318    public static function isDown(): bool
319    {
320        return (self::env('MAINTENANCE_MODE') === true);
321    }
322
323    /**
324     * Check if application is in not maintenance mode
325     *
326     * @return bool
327     */
328    public static function isUp(): bool
329    {
330        return (self::env('MAINTENANCE_MODE') === false);
331    }
332
333    /**
334     * Check if application is in not maintenance mode
335     *
336     * @return bool
337     */
338    public static function isSecretRequest(): bool
339    {
340        if (isset($_GET['secret'])) {
341            $secret = $_GET['secret'];
342            setcookie('pop_mm_secret', $secret);
343        } else {
344            $secret = $_COOKIE['pop_mm_secret'] ?? null;
345        }
346
347        return (!empty($secret) && ($secret == App::env('MAINTENANCE_MODE_SECRET')));
348    }
349
350}