ConfiguredExtension::getFunctions()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 11
ccs 0
cts 5
cp 0
rs 10
cc 2
nc 2
nop 0
crap 6
1
<?php
2
3
namespace Leonidas\Library\Core\View\Twig;
4
5
use RuntimeException;
6
use Throwable;
7
use Twig\Extension\ExtensionInterface;
8
use Twig\TwigFilter;
9
use Twig\TwigFunction;
10
use Twig\TwigTest;
11
12
class ConfiguredExtension implements ExtensionInterface
13
{
14
    protected array $config;
15
16
    public function __construct(array $config)
17
    {
18
        $this->config = $config;
19
    }
20
21
    public function getTokenParsers(): array
22
    {
23
        return array_map(
24
            fn ($parser) => new $parser(),
25
            $this->get('token_parsers')
26
        );
27
    }
28
29
    public function getNodeVisitors(): array
30
    {
31
        return array_map(
32
            fn ($visitor) => new $visitor(),
33
            $this->get('node_visitors')
34
        );
35
    }
36
37
    /**
38
     * @link https://twig.symfony.com/doc/3.x/advanced.html#filters
39
     */
40
    public function getFilters(): array
41
    {
42
        $filters = [];
43
44
        foreach ($this->get('filters') as $filter => $callable) {
45
            $this->resolveCallableArgs($filter, $callable, $options);
46
47
            $filters[] = new TwigFilter($filter, $callable, $options);
48
        }
49
50
        return $filters;
51
    }
52
53
    public function getTests(): array
54
    {
55
        $tests = [];
56
57
        foreach ($this->get('tests') as $test => $callable) {
58
            $this->resolveCallableArgs($test, $callable, $options);
59
60
            $tests[] = new TwigTest($test, $callable, $options);
61
        }
62
63
        return $tests;
64
    }
65
66
    /**
67
     * @link https://twig.symfony.com/doc/3.x/advanced.html#functions
68
     */
69
    public function getFunctions(): array
70
    {
71
        $functions = [];
72
73
        foreach ($this->get('functions') as $function => $callable) {
74
            $this->resolveCallableArgs($function, $callable, $options);
75
76
            $functions[] = new TwigFunction($function, $callable, $options);
77
        }
78
79
        return $functions;
80
    }
81
82
    public function getOperators()
83
    {
84
        $operators = $this->get('operators');
85
86
        return [$operators['unary'] ?? [], $operators['binary'] ?? []];
87
    }
88
89
    protected function get(string $key): array
90
    {
91
        return $this->config[$key] ?? [];
92
    }
93
94
    /**
95
     * Converts arguments into values suitable for construction of
96
     * Twig\TwigFunction and Twig\TwigFilter objects.
97
     *
98
     * @param int|string $name Must be derived from the definition key/index. If
99
     * int and $argument is resolved as string, it will inherit that value.
100
     *
101
     * @param callable|array $callable May either be the callable to use or an
102
     * array containing 'function' and/or 'options' keys. If the latter, will be
103
     * resolved to callable|null via 'function' entry.
104
     *
105
     * @param mixed $options Should be null variable on entry. Value will be
106
     * resolved from $argument['options'] or as an empty array if $argument is
107
     * of type callable.
108
     */
109
    protected function resolveCallableArgs(&$name, &$callable, &$options): void
110
    {
111
        $options = [];
112
113
        if (is_array($callable) && !is_callable($callable)) {
114
            try {
115
                $options = $callable['options'];
116
                $callable = $callable['function'];
117
            } catch (Throwable $e) {
118
                if (str_contains($e->getMessage(), 'options')) {
119
                    $m = "Definition for entry {$name} either missing \"options\" key or invalid callable was provided.";
120
121
                    throw new RuntimeException($m, 0, $e);
122
                }
123
124
                throw $e;
125
            }
126
        } elseif (is_int($name) && is_string($callable)) {
127
            $name = $callable;
128
        }
129
    }
130
}
131