Test Setup Failed
Push — main ( aa8716...cc6c96 )
by Loïc
03:28
created

RoutingExtension   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
dl 0
loc 69
ccs 21
cts 21
cp 1
rs 10
c 1
b 0
f 0
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAttributeIf() 0 8 2
A __construct() 0 3 1
A getControllerFqcn() 0 25 4
A getAriaCurrentPageIf() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Twig\Extension;
6
7
use Symfony\Component\Routing\RouterInterface;
8
use Twig\Attribute\AsTwigFunction;
9
10
use function Symfony\Component\String\u;
11
12
/**
13
 * Routing related stuff.
14
 *
15
 * @see RoutingExtensionTest
16
 */
17
final class RoutingExtension
18
{
19
    /**
20
     * @var array<int, string>|null
21
     */
22
    private ?array $controllers = null;
23
24
    public function __construct(
25 15
        private readonly RouterInterface $router,
26
    ) {
27
    }
28 15
29
    /**
30 6
     * This function returns a complete controller FQCN from a short name.
31
     * If you have multiple controllers/actions with the same name, you can include
32 6
     * the parent namespace to select the good one like the last examples below.
33 6
     *
34 6
     * @example ComposerAction      --> App\Controller\ComposerAction
35 6
     * @example Product\ListAction  --> App\Controller\Product\ListAction
36 6
     * @example Category\ListAction --> App\Controller\Category\ListAction
37
     *
38
     * @return class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
39
     */
40
    #[AsTwigFunction('ctrl_fqcn')]
41
    public function getControllerFqcn(string $ctrlShortname): string
42
    {
43
        if ($this->controllers === null) {
44
            $this->controllers = array_unique(array_map(
45
                static fn ($value) => u($value)->trimSuffix('::__invoke')->toString(),
46
                array_keys($this->router->getRouteCollection()->getAliases())
47
            ));
48
        }
49
50 11
        foreach ($this->controllers as $controller) {
51
            /** @var class-string $controller */
52 11
            if (u($controller)->endsWith($ctrlShortname)) {
53 11
                return $controller;
54 11
            }
55 11
        }
56 11
57
        // If all your ADR controllers live in the "App\Controller\" namespace,
58
        // then you probably don't need all the code above, just use:
59 11
        //
60
        // return  'App\\Controller\\'. $ctrlShortname;
61 11
        //
62 10
        // If the route is not found, then Twig raises a "RouteNotFoundException".
63
64
        throw new \InvalidArgumentException('No controller found for the "'.$ctrlShortname.'" shortname.');
65
    }
66
67
    /**
68
     * Returns an HTML attribute with a given value only if a condition is met.
69
     *
70
     * @see templates/base.html.twig
71
     */
72
    #[AsTwigFunction('attr_if')]
73 1
    public function getAttributeIf(bool $condition, string $attribute, string $value): string
74
    {
75
        if (!$condition) {
76
            return '';
77
        }
78
79
        return \sprintf(' %s="%s"', $attribute, $value);
80
    }
81 10
82
    #[AsTwigFunction('aria_current_page_if')]
83 10
    public function getAriaCurrentPageIf(bool $condition): string
84 10
    {
85
        return $this->getAttributeIf($condition, 'aria-current', 'page');
86
    }
87
}
88