Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
176 / 176
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Routes
100.00% covered (success)
100.00%
176 / 176
100.00% covered (success)
100.00%
9 / 9
13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 add
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
1 / 1
3
 catchallRoute
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 addAuth
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addUser
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addSystem
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 addPanel
100.00% covered (success)
100.00%
66 / 66
100.00% covered (success)
100.00%
1 / 1
1
 addOldPanelApi
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 addApi
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray;
6
7use Celemas\Core\App;
8use Celemas\Core\Factory\Factory;
9use Celemas\Quma\Database;
10use Celemas\Router\Group;
11use Celemas\Router\Route;
12use Cosray\Controller\Auth;
13use Cosray\Controller\Embed;
14use Cosray\Controller\Media;
15use Cosray\Controller\Nodes;
16use Cosray\Controller\OldPanel;
17use Cosray\Controller\Page;
18use Cosray\Controller\Panel;
19use Cosray\Controller\User;
20use Cosray\Middleware\InitRequest;
21use Cosray\Middleware\PanelAuth;
22use Cosray\Middleware\Session;
23
24class Routes
25{
26    private const string LEGACY_PANEL_PATH = '/panel';
27
28    protected string $panelPath;
29    protected string $oldPanelApiPath;
30    protected ?string $apiPath;
31    protected InitRequest $initRequestMiddlware;
32    protected Session $session;
33    protected bool $frontendSession;
34
35    public function __construct(
36        protected Config $config,
37        protected Database $db,
38        protected Factory $factory,
39    ) {
40        $this->panelPath = $config->panel->path;
41        $this->oldPanelApiPath = self::LEGACY_PANEL_PATH . '/api';
42        $this->apiPath = $config->path->api;
43        $this->frontendSession = $config->session->enabled;
44        $this->initRequestMiddlware = new InitRequest($config);
45        $this->session = new Session($this->config, $this->db);
46    }
47
48    public function add(App $app): void
49    {
50        $sessionIfEnabled = [
51            $app->get('/', [Page::class, 'catchall'], 'cms.index.get'),
52            $app->post('/', [Page::class, 'catchall'], 'cms.index.post'),
53            $app->get('/media/image/...slug', [Media::class, 'image'], 'cms.media.image'),
54            $app->get('/media/file/...slug', [Media::class, 'file'], 'cms.media.file'),
55            $app->get('/media/video/...slug', [Media::class, 'file'], 'cms.media.video'),
56            $app->get('/preview/...slug', [Page::class, 'preview'], 'cms.preview.catchall'),
57        ];
58
59        $app->post(
60            '/media/{mediatype:(image|file|video)}/{doctype:(node|menu)}/{uid:[A-Za-z0-9-_.]{1,64}}',
61            [Media::class, 'upload'],
62            'cms.media.upload',
63        )->middleware($this->session);
64
65        // TODO: remove when new panel is finished
66        $this->addOldPanelApi($app, $this->session);
67
68        $this->addApi($app);
69
70        // TODO: remove when new panel is finished
71        // OLD PANEL ROUTES
72        $app->get(
73            self::LEGACY_PANEL_PATH . '/boot',
74            [OldPanel::class, 'boot'],
75            'cms.oldpanel.boot',
76        )->after(new JsonRenderer($this->factory));
77        $app->get(
78            self::LEGACY_PANEL_PATH
79            . '/embed/{token:[A-Za-z0-9]{1,128}}/node/{type:[A-Za-z0-9-_.]{1,64}}/create',
80            [Embed::class, 'create'],
81            'cms.panel.embed.create',
82        )->middleware($this->session);
83        $app->get(
84            self::LEGACY_PANEL_PATH
85            . '/embed/{token:[A-Za-z0-9]{1,128}}/node/{type:[A-Za-z0-9-_.]{1,64}}/{node:[A-Za-z0-9-_.]{1,64}}',
86            [Embed::class, 'node'],
87            'cms.panel.embed.node',
88        )->middleware($this->session);
89        $app->get(
90            self::LEGACY_PANEL_PATH . '/...slug',
91            [OldPanel::class, 'catchall'],
92            'cms.oldpanel.catchall',
93        )->middleware($this->session);
94        $app->get(
95            self::LEGACY_PANEL_PATH,
96            [OldPanel::class, 'index'],
97            'cms.oldpanel',
98        )->middleware($this->session);
99        $app->get(
100            self::LEGACY_PANEL_PATH . '/',
101            [OldPanel::class, 'index'],
102            'cms.oldpanel.slash',
103        )->middleware($this->session);
104        // END OLD PANEL ROUTES
105
106        $this->addPanel($app);
107
108        if ($this->frontendSession) {
109            foreach ($sessionIfEnabled as $route) {
110                $route->middleware($this->session);
111            }
112        }
113    }
114
115    public function catchallRoute(): Route
116    {
117        $catchallRoute = Route::map(
118            ['GET', 'POST'],
119            '/...slug',
120            [Page::class, 'catchall'],
121            'cms.catchall',
122        )->middleware($this->initRequestMiddlware);
123
124        if ($this->frontendSession) {
125            $catchallRoute->middleware($this->session);
126        }
127
128        return $catchallRoute;
129    }
130
131    protected function addAuth(Group $api): void
132    {
133        $api->get('/me', [Auth::class, 'me'], 'auth.user');
134        $api->post('/login', [Auth::class, 'login'], 'auth.login');
135        $api->post('/token-login', [Auth::class, 'tokenLogin'], 'auth.login.token');
136        $api->post('/invalidate-token', [Auth::class, 'invalidateToken'], 'auth.token.invalidate');
137        $api->get('/login/token', [Auth::class, 'token'], 'auth.token');
138        $api->post('/logout', [Auth::class, 'logout'], 'auth.logout');
139    }
140
141    protected function addUser(Group $api): void
142    {
143        $api->get('/users', [User::class, 'list'], 'users');
144        $api->get('/user/{uid:[A-Za-z0-9-_.]{1,64}}', [User::class, 'get'], 'user.get');
145        $api->post('/user', [User::class, 'create'], 'user.create');
146        $api->put('/user/{uid:[A-Za-z0-9-_.]{1,64}}', [User::class, 'save'], 'user.save');
147        $api->get('/profile', [User::class, 'profile'], 'profile.get');
148        $api->put('/profile', [User::class, 'saveProfile'], 'profile.save');
149    }
150
151    protected function addSystem(Group $api): void
152    {
153        $api->get('/collections', [OldPanel::class, 'collections'], 'collections');
154        $api->get('/collection/{collection}', [OldPanel::class, 'collection'], 'collection');
155        $api->get('/nodes', [Nodes::class, 'get'], 'nodes.search.get');
156        $api->post('/nodes', [Nodes::class, 'get'], 'nodes.search.post');
157        $api->get('/node/{uid:[A-Za-z0-9-_.]{1,64}}', [OldPanel::class, 'node'], 'node.get');
158        $api->put('/node/{uid:[A-Za-z0-9-_.]{1,64}}', [OldPanel::class, 'node'], 'node.update');
159        $api->delete('/node/{uid:[A-Za-z0-9-_.]{1,64}}', [OldPanel::class, 'node'], 'node.delete');
160        $api->post('/node/{type}/paths', [OldPanel::class, 'nodePaths'], 'node.paths');
161        $api->post('/node/{type}', [OldPanel::class, 'createNode'], 'node.create');
162        $api->get('/blueprint/{type}', [OldPanel::class, 'blueprint'], 'node.blueprint');
163    }
164
165    protected function addPanel(App $app): void
166    {
167        $app->group(
168            $this->panelPath,
169            function (Group $panel) use ($app) {
170                $renderers = new PanelRenderers($app);
171                $panelAuth = new PanelAuth(
172                    $this->config,
173                    new Users($this->db),
174                    $this->factory,
175                );
176                $panel->middleware($this->session);
177
178                $panel
179                    ->get('/login', [Panel\Login::class, 'login'], 'login')
180                    ->after($renderers->get('login'));
181                $panel
182                    ->post('/login', [Panel\Login::class, 'authenticate'], 'login.authenticate')
183                    ->after($renderers->get('login'));
184                $panel
185                    ->post('/logout', [Panel\Login::class, 'logout'], 'logout')
186                    ->middleware($panelAuth);
187                $panel
188                    ->get(
189                        '',
190                        [Panel\Index::class, 'index'],
191                        'index',
192                    )
193                    ->middleware($panelAuth)
194                    ->after($renderers->get('index'));
195                $panel
196                    ->get(
197                        '/assets/...slug',
198                        [Panel\Assets::class, 'asset'],
199                        'asset',
200                    );
201                $panel
202                    ->get(
203                        '/build/...slug',
204                        [Panel\Assets::class, 'build'],
205                        'build.asset',
206                    );
207                $panel
208                    ->get(
209                        '/collection/{collection}',
210                        [Panel\Collection::class, 'collection'],
211                        'collection',
212                    )
213                    ->middleware($panelAuth)
214                    ->after($renderers->get('collection'));
215                $panel
216                    ->get(
217                        '/collection/{collection}/create/{type:[A-Za-z0-9-_.]{1,64}}',
218                        [Panel\Editor::class, 'create'],
219                        'editor.create',
220                    )
221                    ->middleware($panelAuth)
222                    ->after($renderers->get('editor'));
223                $panel
224                    ->get(
225                        '/collection/{collection}/{node:[A-Za-z0-9-_.]{1,64}}',
226                        [Panel\Editor::class, 'edit'],
227                        'editor',
228                    )
229                    ->middleware($panelAuth)
230                    ->after($renderers->get('editor'));
231            },
232            'cms.panel.',
233        );
234    }
235
236    protected function addOldPanelApi(App $app, Session $session): void
237    {
238        $app->group(
239            $this->oldPanelApiPath,
240            function (Group $api) use ($session) {
241                $api->after(new JsonRenderer($this->factory));
242                $api->middleware($session);
243
244                $this->addAuth($api);
245                $this->addUser($api);
246                $this->addSystem($api);
247            },
248            'cms.oldpanel.api.',
249        );
250    }
251
252    protected function addApi(App $app): void
253    {
254        if ($this->apiPath !== null) {
255            $app->group(
256                $this->apiPath,
257                function (Group $api) {
258                    $api->after(new JsonRenderer($this->factory));
259
260                    $this->addAuth($api);
261                    $this->addUser($api);
262                    $this->addSystem($api);
263                },
264                'cms.api.',
265            );
266        }
267    }
268}