xref: /webtrees/app/Factories/RouteFactory.php (revision 449b311ecf65f677a2595e1e29f712d11ef22f34)
1208909d8SGreg Roach<?php
2208909d8SGreg Roach
3208909d8SGreg Roach/**
4208909d8SGreg Roach * webtrees: online genealogy
5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team
6208909d8SGreg Roach * This program is free software: you can redistribute it and/or modify
7208909d8SGreg Roach * it under the terms of the GNU General Public License as published by
8208909d8SGreg Roach * the Free Software Foundation, either version 3 of the License, or
9208909d8SGreg Roach * (at your option) any later version.
10208909d8SGreg Roach * This program is distributed in the hope that it will be useful,
11208909d8SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12208909d8SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13208909d8SGreg Roach * GNU General Public License for more details.
14208909d8SGreg Roach * You should have received a copy of the GNU General Public License
15208909d8SGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>.
16208909d8SGreg Roach */
17208909d8SGreg Roach
18208909d8SGreg Roachdeclare(strict_types=1);
19208909d8SGreg Roach
20208909d8SGreg Roachnamespace Fisharebest\Webtrees\Factories;
21208909d8SGreg Roach
22158900c2SGreg Roachuse Aura\Router\Map;
23158900c2SGreg Roachuse Aura\Router\Route;
24208909d8SGreg Roachuse Aura\Router\RouterContainer;
25208909d8SGreg Roachuse Fisharebest\Webtrees\Contracts\RouteFactoryInterface;
26208909d8SGreg Roachuse Fisharebest\Webtrees\Html;
27d35568b4SGreg Roachuse Fisharebest\Webtrees\Registry;
28208909d8SGreg Roachuse Fisharebest\Webtrees\Validator;
29208909d8SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
30208909d8SGreg Roach
31208909d8SGreg Roachuse function array_filter;
3219033cfeSGreg Roachuse function array_map;
33158900c2SGreg Roachuse function is_bool;
34208909d8SGreg Roachuse function parse_url;
35208909d8SGreg Roachuse function strlen;
36208909d8SGreg Roachuse function substr;
37208909d8SGreg Roach
38208909d8SGreg Roachuse const ARRAY_FILTER_USE_KEY;
39208909d8SGreg Roachuse const PHP_URL_PATH;
40208909d8SGreg Roach
41208909d8SGreg Roach/**
42208909d8SGreg Roach * Make a URL for a route.
43208909d8SGreg Roach */
44208909d8SGreg Roachclass RouteFactory implements RouteFactoryInterface
45208909d8SGreg Roach{
46208909d8SGreg Roach    /**
47208909d8SGreg Roach     * Generate a URL for a named route.
48208909d8SGreg Roach     *
49208909d8SGreg Roach     * @param string                                    $route_name
50208909d8SGreg Roach     * @param array<bool|int|string|array<string>|null> $parameters
51208909d8SGreg Roach     *
52208909d8SGreg Roach     * @return string
53208909d8SGreg Roach     */
54208909d8SGreg Roach    public function route(string $route_name, array $parameters = []): string
55208909d8SGreg Roach    {
56d35568b4SGreg Roach        $request  = Registry::container()->get(ServerRequestInterface::class);
57208909d8SGreg Roach        $base_url = Validator::attributes($request)->string('base_url');
58158900c2SGreg Roach        $route    = $this->routeMap()->getRoute($route_name);
59158900c2SGreg Roach
60158900c2SGreg Roach        // Generate the URL.
61d35568b4SGreg Roach        $router_container = Registry::container()->get(RouterContainer::class);
62208909d8SGreg Roach
63158900c2SGreg Roach        // webtrees uses http_build_query() to generate URLs - which maps false onto "0".
64158900c2SGreg Roach        // Aura uses rawurlencode(), which maps false onto "" - which does not work as an aura URL parameter.
65158900c2SGreg Roach        $parameters = array_map(static fn ($var) => is_bool($var) ? (int) $var : $var, $parameters);
66208909d8SGreg Roach
676777192fSGreg Roach        // Aura doesn't work with empty/optional URL parameters - but we need empty ones for query parameters.
686777192fSGreg Roach        $url_parameters = array_map(static fn ($var) => $var === '' ? null : $var, $parameters);
6919033cfeSGreg Roach
706777192fSGreg Roach        $url = $router_container->getGenerator()->generate($route_name, $url_parameters);
71208909d8SGreg Roach
72208909d8SGreg Roach        // Aura ignores parameters that are not tokens.  We need to add them as query parameters.
73*f25fc0f9SGreg Roach        $parameters = array_filter($parameters, static fn (string $key): bool => !str_contains($route->path, '{' . $key . '}') && !str_contains($route->path, '{/' . $key . '}'), ARRAY_FILTER_USE_KEY);
74208909d8SGreg Roach
75208909d8SGreg Roach        if (Validator::attributes($request)->boolean('rewrite_urls', false)) {
76208909d8SGreg Roach            // Make the pretty URL absolute.
77208909d8SGreg Roach            $base_path = parse_url($base_url, PHP_URL_PATH) ?: '';
78208909d8SGreg Roach            $url       = $base_url . substr($url, strlen($base_path));
79208909d8SGreg Roach        } else {
80208909d8SGreg Roach            // Turn the pretty URL into an ugly one.
81208909d8SGreg Roach            $path       = parse_url($url, PHP_URL_PATH);
82208909d8SGreg Roach            $parameters = ['route' => $path] + $parameters;
83208909d8SGreg Roach            $url        = $base_url . '/index.php';
84208909d8SGreg Roach        }
85208909d8SGreg Roach
86208909d8SGreg Roach        return Html::url($url, $parameters);
87208909d8SGreg Roach    }
88158900c2SGreg Roach
89158900c2SGreg Roach    /**
90158900c2SGreg Roach     * @return Map<Route>
91158900c2SGreg Roach     */
92158900c2SGreg Roach    public function routeMap(): Map
93158900c2SGreg Roach    {
94d35568b4SGreg Roach        $router_container = Registry::container()->get(RouterContainer::class);
95158900c2SGreg Roach
96158900c2SGreg Roach        return $router_container->getMap();
97158900c2SGreg Roach    }
98208909d8SGreg Roach}
99