Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
29 / 29 |
|
100.00% |
8 / 8 |
CRAP | |
100.00% |
1 / 1 |
MimeTypes | |
100.00% |
29 / 29 |
|
100.00% |
8 / 8 |
17 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
getMimeTypes | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getMimeType | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getMimeTypeNameFromFileExtension | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
getFileExtensionsFromMimeTypeName | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
isValidMimeTypeName | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
isValidMimeTypeFileExtension | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
detect | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | |
3 | /** |
4 | * @author: Doug Wilbourne (dougwilbourne@gmail.com) |
5 | */ |
6 | |
7 | declare(strict_types=1); |
8 | |
9 | namespace pvc\http\mime; |
10 | |
11 | use Psr\SimpleCache\CacheInterface; |
12 | use pvc\http\err\MimeTypesUnreadableStreamException; |
13 | use pvc\http\err\UnknownMimeTypeDetectedException; |
14 | use pvc\interfaces\http\mime\MimeTypeInterface; |
15 | use pvc\interfaces\http\mime\MimeTypesInterface; |
16 | use pvc\interfaces\http\mime\MimeTypesSrcInterface; |
17 | use Symfony\Component\Cache\Adapter\FilesystemAdapter; |
18 | use Symfony\Component\Cache\Psr16Cache; |
19 | use Throwable; |
20 | |
21 | /** |
22 | * Class mimetype |
23 | */ |
24 | class MimeTypes implements MimeTypesInterface |
25 | { |
26 | protected MimeTypesSrcInterface $mimeTypesSrc; |
27 | |
28 | protected CacheInterface $cache; |
29 | |
30 | protected string $cacheKey = 'mimeTypes'; |
31 | |
32 | /** |
33 | * @var array<string, MimeTypeInterface> |
34 | */ |
35 | protected array $mimeTypes; |
36 | |
37 | public function __construct( |
38 | ?MimeTypesSrcInterface $src = null, |
39 | ?CacheInterface $cache = null, |
40 | ?int $ttl = null, |
41 | ) |
42 | { |
43 | $this->mimeTypesSrc = $src ?: new MimeTypesSrcJsDelivr(); |
44 | |
45 | if (!$cache instanceof \Psr\SimpleCache\CacheInterface) { |
46 | $psr6Cache = new FilesystemAdapter(); |
47 | $this->cache = new Psr16Cache($psr6Cache); |
48 | } else { |
49 | $this->cache = $cache; |
50 | } |
51 | |
52 | if ($ttl === null) { |
53 | /** |
54 | * valid for one day |
55 | */ |
56 | $ttl = 24 * 60 * 60; |
57 | } |
58 | $this->cache->set($this->cacheKey, $this->mimeTypesSrc->getMimeTypes(), |
59 | $ttl); |
60 | } |
61 | |
62 | /** |
63 | * @return array<string, MimeTypeInterface> |
64 | * @throws \Psr\SimpleCache\InvalidArgumentException |
65 | */ |
66 | public function getMimeTypes(): array |
67 | { |
68 | /** @var array<string, MimeTypeInterface> $result */ |
69 | $result = $this->cache->get($this->cacheKey); |
70 | return $result; |
71 | } |
72 | |
73 | /** |
74 | * @param string $mimeTypeName |
75 | * @return MimeTypeInterface|null |
76 | */ |
77 | public function getMimeType(string $mimeTypeName): ?MimeTypeInterface |
78 | { |
79 | $mimeTypes = $this->getMimeTypes(); |
80 | return $mimeTypes[$mimeTypeName] ?? null; |
81 | } |
82 | |
83 | /** |
84 | * @inheritDoc |
85 | */ |
86 | public function getMimeTypeNameFromFileExtension(string $fileExt): ?string |
87 | { |
88 | foreach ($this->getMimeTypes() as $mimeType) { |
89 | if (in_array($fileExt, $mimeType->getFileExtensions(), true)) { |
90 | return $mimeType->getMimeTypeName(); |
91 | } |
92 | } |
93 | return null; |
94 | } |
95 | |
96 | /** |
97 | * @inheritDoc |
98 | */ |
99 | public function getFileExtensionsFromMimeTypeName(string $mimeTypeName): array |
100 | { |
101 | $mimeTypes = $this->getMimeTypes(); |
102 | $mt = $mimeTypes[$mimeTypeName] ?? null; |
103 | return $mt ? $mt->getFileExtensions() : []; |
104 | } |
105 | |
106 | /** |
107 | * @inheritDoc |
108 | */ |
109 | public function isValidMimeTypeName(string $mimeTypeName): bool |
110 | { |
111 | $mimeTypes = $this->getMimeTypes(); |
112 | return isset($mimeTypes[$mimeTypeName]); |
113 | } |
114 | |
115 | /** |
116 | * { @inheritDoc } |
117 | */ |
118 | public function isValidMimeTypeFileExtension(string $fileExt): bool |
119 | { |
120 | return !is_null($this->getMimeTypeNameFromFileExtension($fileExt)); |
121 | } |
122 | |
123 | /** |
124 | * @param resource $stream |
125 | * @return MimeTypeInterface |
126 | * @throws MimeTypesUnreadableStreamException |
127 | * @throws UnknownMimeTypeDetectedException |
128 | */ |
129 | public function detect($stream): MimeTypeInterface |
130 | { |
131 | /** |
132 | * mime_content_type throws a type error if it is not supplied a valid resource |
133 | */ |
134 | try { |
135 | $detected = mime_content_type($stream); |
136 | } catch (Throwable $e) { |
137 | throw new MimeTypesUnreadableStreamException($e); |
138 | } |
139 | |
140 | /** |
141 | * conceivably could return a mime type that is unknown in the list of mime types supplied by the cdn that |
142 | * this library is using |
143 | */ |
144 | if ((false === $detected) || !$contentMimeType = $this->getMimeType($detected)) { |
145 | throw new UnknownMimeTypeDetectedException($detected); |
146 | } |
147 | return $contentMimeType; |
148 | } |
149 | } |