Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
LegacyMiddleware
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
33
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
12
 loadPage
n/a
0 / 0
n/a
0 / 0
16
 renderPage
n/a
0 / 0
n/a
0 / 0
4
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Middleware;
6
7use Engelsystem\Helpers\Authenticator;
8use Engelsystem\Helpers\Translation\Translator;
9use Engelsystem\Http\Request;
10use Psr\Container\ContainerInterface;
11use Psr\Http\Message\ResponseInterface;
12use Psr\Http\Message\ServerRequestInterface;
13use Psr\Http\Server\MiddlewareInterface;
14use Psr\Http\Server\RequestHandlerInterface;
15
16/**
17 * Middleware to support the old routing / pages from includes
18 */
19class LegacyMiddleware implements MiddlewareInterface
20{
21    /** @var array<string> */
22    protected array $free_pages = [
23        'angeltypes',
24        'public_dashboard',
25        'locations',
26        'shift_entries',
27        'shifts',
28        'users',
29    ];
30
31    public function __construct(protected ContainerInterface $container, protected Authenticator $auth)
32    {
33    }
34
35    /**
36     * Handle the request the old way
37     *
38     * Should be used before a 404 is sent
39     */
40    public function process(
41        ServerRequestInterface $request,
42        RequestHandlerInterface $handler
43    ): ResponseInterface {
44        /** @var Request $appRequest */
45        $appRequest = $this->container->get('request');
46        $page = $appRequest->query->get('p');
47        // Support old URL/permission scheme
48        if (empty($page)) {
49            $page = $appRequest->path();
50            $page = str_replace('-', '_', $page);
51        }
52
53        $allowPage = match ($page) {
54            'admin_arrive' => $this->auth->can('users.arrive.list'),
55            'user_angeltypes' => $this->auth->can('angeltypes.join'),
56            default => false,
57        };
58
59        $title = $content = '';
60        if (
61            preg_match('~^\w+$~i', $page)
62            && (in_array($page, $this->free_pages) || $this->auth->can($page) || $allowPage)
63        ) {
64            list($title, $content) = $this->loadPage($page);
65        }
66
67        if ($content instanceof ResponseInterface) {
68            return $content;
69        }
70
71        if (empty($title) and empty($content)) {
72            /** @var Translator $translator */
73            $translator = $this->container->get('translator');
74
75            $page = 404;
76            $title = $translator->translate('page.404.title');
77            $content = $translator->translate('page.404.text');
78        }
79
80        return $this->renderPage($page, $title, $content);
81    }
82
83    /**
84     * Get the legacy page content and title
85     *
86     * @return array ['title', 'content']
87     * @codeCoverageIgnore
88     */
89    protected function loadPage(string $page): array
90    {
91        switch ($page) {
92            case 'public_dashboard':
93                return public_dashboard_controller();
94            case 'angeltypes':
95                return angeltypes_controller();
96            case 'shift_entries':
97                return shift_entries_controller();
98            case 'shifts':
99                return shifts_controller();
100            case 'users':
101                return users_controller();
102            case 'user_angeltypes':
103                return user_angeltypes_controller();
104            case 'locations':
105                return locations_controller();
106            case 'user_myshifts':
107                $title = myshifts_title();
108                $content = user_myshifts();
109                return [$title, $content];
110            case 'user_shifts':
111                $title = shifts_title();
112                $content = user_shifts();
113                return [$title, $content];
114            case 'admin_user':
115                $title = admin_user_title();
116                $content = admin_user();
117                return [$title, $content];
118            case 'admin_arrive':
119                $title = admin_arrive_title();
120                $content = admin_arrive();
121                return [$title, $content];
122            case 'admin_active':
123                $title = admin_active_title();
124                $content = admin_active();
125                return [$title, $content];
126            case 'admin_free':
127                $title = admin_free_title();
128                $content = admin_free();
129                return [$title, $content];
130            case 'admin_groups':
131                $title = admin_groups_title();
132                $content = admin_groups();
133                return [$title, $content];
134            case 'admin_shifts':
135                $title = admin_shifts_title();
136                $content = admin_shifts();
137                return [$title, $content];
138        }
139
140        throw_redirect(url('/login'));
141
142        return [];
143    }
144
145    /**
146     * Render the template
147     *
148     * @codeCoverageIgnore
149     */
150    protected function renderPage(string | int $page, string $title, string $content): ResponseInterface
151    {
152        if (!empty($page) && is_int($page)) {
153            return response($content, $page);
154        }
155
156        if (str_contains($content, '<html')) {
157            return response($content);
158        }
159
160        return response(
161            view(
162                'layouts/app',
163                [
164                    'title'   => $title,
165                    'content' => msg() . $content,
166                ]
167            )
168        );
169    }
170}