• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tempestphp / tempest-framework / 14049246919

24 Mar 2025 09:42PM UTC coverage: 79.353% (-0.04%) from 79.391%
14049246919

push

github

web-flow
feat(support): support array parameters in string manipulations (#1073)

48 of 48 new or added lines in 2 files covered. (100.0%)

735 existing lines in 126 files now uncovered.

10492 of 13222 relevant lines covered (79.35%)

90.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.63
/src/Tempest/View/src/Components/Icon.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\View\Components;
6

7
use DateInterval;
8
use DateTimeImmutable;
9
use Exception;
10
use Tempest\Cache\IconCache;
11
use Tempest\Core\AppConfig;
12
use Tempest\Http\Status;
13
use Tempest\HttpClient\HttpClient;
14
use Tempest\Support\Str\ImmutableString;
15
use Tempest\View\Elements\ViewComponentElement;
16
use Tempest\View\IconConfig;
17
use Tempest\View\ViewComponent;
18

19
final readonly class Icon implements ViewComponent
20
{
21
    public function __construct(
7✔
22
        private AppConfig $appConfig,
23
        private IconCache $iconCache,
24
        private IconConfig $iconConfig,
25
        private HttpClient $http,
26
    ) {}
7✔
27

UNCOV
28
    public static function getName(): string
×
29
    {
UNCOV
30
        return 'x-icon';
×
31
    }
32

33
    public function compile(ViewComponentElement $element): string
7✔
34
    {
35
        $name = $element->getAttribute('name');
7✔
36
        $class = $element->getAttribute('class');
7✔
37

38
        $svg = $this->render($name);
7✔
39

40
        if (! $svg) {
7✔
41
            return $this->appConfig->environment->isLocal()
2✔
42
                ? ('<!-- unknown-icon: ' . $name . ' -->')
1✔
43
                : '';
2✔
44
        }
45

46
        return match ($class) {
5✔
47
            null => $svg,
4✔
48
            default => $this->injectClass($svg, $class),
5✔
49
        };
5✔
50
    }
51

52
    /**
53
     * Downloads the icon's SVG file from the Iconify API
54
     */
55
    private function download(string $prefix, string $name): ?string
7✔
56
    {
57
        try {
58
            $url = new ImmutableString($this->iconConfig->iconifyApiUrl)
7✔
59
                ->finish('/')
7✔
60
                ->append("{$prefix}/{$name}.svg")
7✔
61
                ->toString();
7✔
62

63
            $response = $this->http->get($url);
7✔
64

65
            if ($response->status !== Status::OK) {
7✔
66
                return null;
2✔
67
            }
68

69
            return $response->body;
5✔
UNCOV
70
        } catch (Exception) {
×
71
            return null;
×
72
        }
73
    }
74

75
    /**
76
     * Renders an icon
77
     *
78
     * This method is responsible for rendering the icon. If the icon is not
79
     * in the cache, it will download it on the fly and cache it for future
80
     * use. If the icon is already in the cache, it will be served from there.
81
     */
82
    private function render(string $name): ?string
7✔
83
    {
84
        try {
85
            $parts = explode(':', $name, 2);
7✔
86

87
            if (count($parts) !== 2) {
7✔
UNCOV
88
                return null;
×
89
            }
90

91
            [$prefix, $name] = $parts;
7✔
92

93
            return $this->iconCache->resolve(
7✔
94
                key: "iconify-{$prefix}-{$name}",
7✔
95
                cache: fn () => $this->download($prefix, $name),
7✔
96
                expiresAt: $this->iconConfig->cacheDuration
7✔
UNCOV
97
                    ? new DateTimeImmutable()
×
98
                        ->add(DateInterval::createFromDateString("{$this->iconConfig->cacheDuration} seconds"))
×
99
                    : null,
7✔
100
            );
7✔
UNCOV
101
        } catch (Exception) {
×
102
            return null;
×
103
        }
104
    }
105

106
    /**
107
     * Forwards the user-provided class attribute to the SVG element
108
     */
109
    private function injectClass(string $svg, string $class): string
1✔
110
    {
111
        return new ImmutableString($svg)
1✔
112
            ->replace(
1✔
113
                search: '<svg ',
1✔
114
                replace: "<svg class=\"{$class}\" ",
1✔
115
            )
1✔
116
            ->toString();
1✔
117
    }
118
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc