Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
20 / 22
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Icons
90.91% covered (success)
90.91%
20 / 22
60.00% covered (warning)
60.00%
3 / 5
12.11
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
1
 icon
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
5.01
 providers
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 key
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 failed
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray;
6
7use Celema\Container\Container;
8use Cosray\Icons\Provider;
9
10final class Icons implements Provider
11{
12    /** @var array<string, string> */
13    private array $cache = [];
14
15    public function __construct(
16        private readonly Container $container,
17        private readonly Config $config,
18    ) {}
19
20    /** @param array<array-key, mixed> $args */
21    public function icon(string $id, array $args = []): string
22    {
23        $id = trim($id);
24
25        if ($id === '') {
26            return $this->failed('empty icon id');
27        }
28
29        $key = $this->key($id, $args);
30
31        if (array_key_exists($key, $this->cache)) {
32            return $this->cache[$key];
33        }
34
35        foreach ($this->providers() as $provider) {
36            $svg = $provider->icon($id, $args);
37
38            if ($svg === '') {
39                continue;
40            }
41
42            return $this->cache[$key] = $svg;
43        }
44
45        return $this->cache[$key] = $this->failed('icon not found: ' . $id);
46    }
47
48    /** @return iterable<Provider> */
49    private function providers(): iterable
50    {
51        $tag = $this->container->tag(Provider::class);
52
53        foreach ($tag->entries() as $id) {
54            $provider = $tag->get($id);
55
56            if ($provider instanceof Provider) {
57                yield $provider;
58            }
59        }
60    }
61
62    /** @param array<array-key, mixed> $args */
63    private function key(string $id, array $args): string
64    {
65        return hash('xxh3', $id . "\x1f" . serialize($args));
66    }
67
68    private function failed(string $message): string
69    {
70        if (!$this->config->debug()) {
71            return '';
72        }
73
74        return sprintf('<!-- %s -->', escape($message));
75    }
76}