Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
94.12% covered (success)
94.12%
16 / 17
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
FrontendUrlGenerator
94.12% covered (success)
94.12%
16 / 17
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
5 / 5
50.00% covered (danger)
50.00%
1 / 2
6
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 generate
93.75% covered (success)
93.75%
15 / 16
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
4 / 4
0.00% covered (danger)
0.00%
0 / 1
5
1<?php
2
3namespace App\Shared\Infrastructure\Service;
4
5/**
6 * @author Wilhelm Zwertvaegher
7 */
8readonly class FrontendUrlGenerator
9{
10
11    /**
12     * @param array<string> $frontends
13     * @param array<string, array<string, string>> $routes
14     */
15    public function __construct(private array $frontends, private array $routes)
16    {
17    }
18
19    /**
20     * Generates full URL
21     *
22     * @param string $frontend ex: 'app' or 'admin'
23     * @param string $routeName ex: 'confirm_identity'
24     * @param array<string, string|int> $params ex: ['id' => 123]
25     * @param array<string, string|int> $queryParams ex: ['utm' => 'mail']
26     */
27    public function generate(string $frontend, string $routeName, array $params = [], array $queryParams = []): string
28    {
29        if (!isset($this->frontends[$frontend])) {
30            throw new \InvalidArgumentException(sprintf('Unknown frontend "%s".', $frontend));
31        }
32
33        if (!isset($this->routes[$frontend][$routeName])) {
34            throw new \InvalidArgumentException(sprintf('Unknown route "%s" for frontend "%s".', $routeName, $frontend));
35        }
36
37        $pathTemplate = $this->routes[$frontend][$routeName];
38
39        // params :token ou :id
40        $urlPath = preg_replace_callback('/:(\w+)/', function ($m) use ($params, $routeName) {
41            $key = $m[1];
42            if (!array_key_exists($key, $params)) {
43                throw new \InvalidArgumentException(sprintf('Missing parameter "%s" for route "%s".', $key, $routeName));
44            }
45            return rawurlencode((string)$params[$key]);
46        }, $pathTemplate);
47
48        // assemble base + path
49        $base = rtrim($this->frontends[$frontend], '/');
50        $url = $base . $urlPath;
51
52        if (!empty($queryParams)) {
53            $url .= '?' . http_build_query($queryParams);
54        }
55
56        return $url;
57    }
58}