xref: /webtrees/app/Http/Middleware/Router.php (revision c48210a4385200de2714536e367f26be93c9a9ca)
19e5d8e6fSGreg Roach<?php
29e5d8e6fSGreg Roach
39e5d8e6fSGreg Roach/**
49e5d8e6fSGreg Roach * webtrees: online genealogy
59e5d8e6fSGreg Roach * Copyright (C) 2019 webtrees development team
69e5d8e6fSGreg Roach * This program is free software: you can redistribute it and/or modify
79e5d8e6fSGreg Roach * it under the terms of the GNU General Public License as published by
89e5d8e6fSGreg Roach * the Free Software Foundation, either version 3 of the License, or
99e5d8e6fSGreg Roach * (at your option) any later version.
109e5d8e6fSGreg Roach * This program is distributed in the hope that it will be useful,
119e5d8e6fSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
129e5d8e6fSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
139e5d8e6fSGreg Roach * GNU General Public License for more details.
149e5d8e6fSGreg Roach * You should have received a copy of the GNU General Public License
159e5d8e6fSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
169e5d8e6fSGreg Roach */
179e5d8e6fSGreg Roachdeclare(strict_types=1);
189e5d8e6fSGreg Roach
199e5d8e6fSGreg Roachnamespace Fisharebest\Webtrees\Http\Middleware;
209e5d8e6fSGreg Roach
219e5d8e6fSGreg Roachuse Fig\Http\Message\RequestMethodInterface;
22*c48210a4SGreg Roachuse Fisharebest\Webtrees\Webtrees;
239e5d8e6fSGreg Roachuse Illuminate\Support\Str;
249e5d8e6fSGreg Roachuse Psr\Http\Message\ResponseInterface;
259e5d8e6fSGreg Roachuse Psr\Http\Message\ServerRequestInterface;
269e5d8e6fSGreg Roachuse Psr\Http\Server\MiddlewareInterface;
279e5d8e6fSGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
289e5d8e6fSGreg Roach
299e5d8e6fSGreg Roachuse function app;
309e5d8e6fSGreg Roachuse function explode;
319e5d8e6fSGreg Roach
329e5d8e6fSGreg Roach/**
339e5d8e6fSGreg Roach * Simple class to help migrate to a third-party routing library.
349e5d8e6fSGreg Roach */
359e5d8e6fSGreg Roachclass Router implements MiddlewareInterface, RequestMethodInterface
369e5d8e6fSGreg Roach{
379e5d8e6fSGreg Roach    private const CONTROLLER_NAMESPACE = '\\Fisharebest\\Webtrees\\Http\\Controllers\\';
389e5d8e6fSGreg Roach
399e5d8e6fSGreg Roach    // To parse Controller::action
409e5d8e6fSGreg Roach    private const SCOPE_OPERATOR = '::';
419e5d8e6fSGreg Roach
429e5d8e6fSGreg Roach    /** @var string[][] */
439e5d8e6fSGreg Roach    private $routes = [
449e5d8e6fSGreg Roach        self::METHOD_GET  => [],
459e5d8e6fSGreg Roach        self::METHOD_POST => [],
469e5d8e6fSGreg Roach    ];
479e5d8e6fSGreg Roach
489e5d8e6fSGreg Roach    /**
499e5d8e6fSGreg Roach     * @param string $path
509e5d8e6fSGreg Roach     * @param string $handler
519e5d8e6fSGreg Roach     *
529e5d8e6fSGreg Roach     * @return Router
539e5d8e6fSGreg Roach     */
549e5d8e6fSGreg Roach    public function get(string $path, string $handler): Router
559e5d8e6fSGreg Roach    {
569e5d8e6fSGreg Roach        return $this->add(self::METHOD_GET, $path, $handler);
579e5d8e6fSGreg Roach    }
589e5d8e6fSGreg Roach
599e5d8e6fSGreg Roach    /**
609e5d8e6fSGreg Roach     * @param string $method
619e5d8e6fSGreg Roach     * @param string $path
629e5d8e6fSGreg Roach     * @param string $handler
639e5d8e6fSGreg Roach     *
649e5d8e6fSGreg Roach     * @return Router
659e5d8e6fSGreg Roach     */
669e5d8e6fSGreg Roach    private function add(string $method, string $path, string $handler): Router
679e5d8e6fSGreg Roach    {
689e5d8e6fSGreg Roach        $this->routes[$method][$path] = $handler;
699e5d8e6fSGreg Roach
709e5d8e6fSGreg Roach        return $this;
719e5d8e6fSGreg Roach    }
729e5d8e6fSGreg Roach
739e5d8e6fSGreg Roach    /**
749e5d8e6fSGreg Roach     * @param string $path
759e5d8e6fSGreg Roach     * @param string $handler
769e5d8e6fSGreg Roach     *
779e5d8e6fSGreg Roach     * @return Router
789e5d8e6fSGreg Roach     */
799e5d8e6fSGreg Roach    public function post(string $path, string $handler): Router
809e5d8e6fSGreg Roach    {
819e5d8e6fSGreg Roach        return $this->add(self::METHOD_POST, $path, $handler);
829e5d8e6fSGreg Roach    }
839e5d8e6fSGreg Roach
849e5d8e6fSGreg Roach    /**
859e5d8e6fSGreg Roach     * @param ServerRequestInterface  $request
869e5d8e6fSGreg Roach     * @param RequestHandlerInterface $handler
879e5d8e6fSGreg Roach     *
889e5d8e6fSGreg Roach     * @return ResponseInterface
899e5d8e6fSGreg Roach     */
909e5d8e6fSGreg Roach    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
919e5d8e6fSGreg Roach    {
929e5d8e6fSGreg Roach        app()->instance(self::class, $this);
93*c48210a4SGreg Roach        require Webtrees::ROOT_DIR . 'routes/web.php';
949e5d8e6fSGreg Roach
959e5d8e6fSGreg Roach        $method  = $request->getMethod();
969e5d8e6fSGreg Roach        $route   = $request->getQueryParams()['route'] ?? '';
979e5d8e6fSGreg Roach        $routing = $this->routes[$method][$route] ?? '';
989e5d8e6fSGreg Roach
999e5d8e6fSGreg Roach        // Bind the request into the container
1009e5d8e6fSGreg Roach        app()->instance(ServerRequestInterface::class, $request);
1019e5d8e6fSGreg Roach
1029e5d8e6fSGreg Roach        // No route matched?
1039e5d8e6fSGreg Roach        if ($routing === '') {
1049e5d8e6fSGreg Roach            return $handler->handle($request);
1059e5d8e6fSGreg Roach        }
1069e5d8e6fSGreg Roach
1079e5d8e6fSGreg Roach        // Routes defined using controller::action
1089e5d8e6fSGreg Roach        if (Str::contains($routing, self::SCOPE_OPERATOR)) {
1099e5d8e6fSGreg Roach            [$class, $method] = explode(self::SCOPE_OPERATOR, $routing);
1109e5d8e6fSGreg Roach
1119e5d8e6fSGreg Roach            return app(self::CONTROLLER_NAMESPACE . $class)->$method($request);
1129e5d8e6fSGreg Roach        }
1139e5d8e6fSGreg Roach
1149e5d8e6fSGreg Roach        // Routes defined using a request handler
1159e5d8e6fSGreg Roach        return app($routing)->handle($request);
1169e5d8e6fSGreg Roach    }
1179e5d8e6fSGreg Roach}
118