Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
44.74% |
17 / 38 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
BaseWebsource | |
44.74% |
17 / 38 |
|
0.00% |
0 / 5 |
65.78 | |
0.00% |
0 / 1 |
spawn | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFileSystem | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getFileStream | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
getMimetype | |
80.95% |
17 / 21 |
|
0.00% |
0 / 1 |
10.69 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; under version 2 |
7 | * of the License (non-upgradable). |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * |
18 | * Copyright (c) 2013-2025 (original work) Open Assessment Technologies SA; |
19 | */ |
20 | |
21 | namespace oat\tao\model\websource; |
22 | |
23 | use common_Exception; |
24 | use common_exception_Error; |
25 | use common_exception_NotFound; |
26 | use GuzzleHttp\Psr7\Stream; |
27 | use oat\oatbox\Configurable; |
28 | use oat\oatbox\filesystem\FileSystem; |
29 | use oat\oatbox\filesystem\FilesystemException; |
30 | use oat\oatbox\filesystem\FileSystemService; |
31 | use oat\oatbox\service\ServiceManager; |
32 | use Psr\Http\Message\StreamInterface; |
33 | use tao_helpers_File; |
34 | use tao_models_classes_FileNotFoundException; |
35 | |
36 | /** |
37 | * @author Joel Bout, <joel@taotesting.com> |
38 | */ |
39 | abstract class BaseWebsource extends Configurable implements Websource |
40 | { |
41 | public const OPTION_ID = 'id'; |
42 | public const OPTION_FILESYSTEM_ID = 'fsUri'; |
43 | private const ALLOWED_SVGZ_MIMETYPES = ['text/plain', 'image/svg', 'application/x-gzip']; |
44 | |
45 | /** |
46 | * Filesystem that is being made available |
47 | */ |
48 | protected $fileSystem = null; |
49 | |
50 | /** |
51 | * Identifier of the Access Provider |
52 | * |
53 | * @var string |
54 | */ |
55 | private $id; |
56 | |
57 | /** |
58 | * Used to instantiate new AccessProviders |
59 | * @param $fileSystemId |
60 | * @param array $customConfig |
61 | * @return BaseWebsource |
62 | * @throws common_Exception |
63 | */ |
64 | protected static function spawn($fileSystemId, $customConfig = []) |
65 | { |
66 | $customConfig[self::OPTION_FILESYSTEM_ID] = $fileSystemId; |
67 | $customConfig[self::OPTION_ID] = uniqid(); |
68 | $webSource = new static($customConfig); |
69 | WebsourceManager::singleton()->addWebsource($webSource); |
70 | |
71 | return $webSource; |
72 | } |
73 | |
74 | /** |
75 | * Return the identifer of the AccessProvider |
76 | * |
77 | * @return string |
78 | */ |
79 | public function getId() |
80 | { |
81 | return $this->getOption(self::OPTION_ID); |
82 | } |
83 | |
84 | /** |
85 | * @return null|FileSystem |
86 | * @throws common_exception_Error |
87 | * @throws common_exception_NotFound |
88 | */ |
89 | public function getFileSystem() |
90 | { |
91 | if ($this->fileSystem === null) { |
92 | /** @var FileSystemService $fsService */ |
93 | $fsService = ServiceManager::getServiceManager()->get(FileSystemService::SERVICE_ID); |
94 | $this->fileSystem = $fsService->getFileSystem($this->getOption(self::OPTION_FILESYSTEM_ID)); |
95 | } |
96 | return $this->fileSystem; |
97 | } |
98 | |
99 | /** |
100 | * @param $filePath |
101 | * @return StreamInterface |
102 | * @throws common_exception_Error |
103 | * @throws common_exception_NotFound |
104 | * @throws tao_models_classes_FileNotFoundException |
105 | */ |
106 | public function getFileStream($filePath) |
107 | { |
108 | if ($filePath === '') { |
109 | throw new tao_models_classes_FileNotFoundException("Empty file path"); |
110 | } |
111 | $fs = $this->getFileSystem(); |
112 | try { |
113 | $resource = $fs->readStream($filePath); |
114 | } catch (FilesystemException $e) { |
115 | throw new tao_models_classes_FileNotFoundException($filePath); |
116 | } |
117 | return new Stream($resource, ['size' => $fs->fileSize($filePath)]); |
118 | } |
119 | |
120 | /** |
121 | * Get a file's mime-type. |
122 | * @param string $filePath The path to the file. |
123 | * @return string|false The file mime-type or false on failure. |
124 | * @throws common_exception_Error |
125 | * @throws common_exception_NotFound |
126 | * @throws FilesystemException |
127 | */ |
128 | public function getMimetype($filePath) |
129 | { |
130 | $mimeType = $this->getFileSystem()->mimeType($filePath); |
131 | |
132 | $pathParts = pathinfo($filePath); |
133 | if (!isset($pathParts['extension'])) { |
134 | return $mimeType; |
135 | } |
136 | |
137 | switch ($pathParts['extension']) { |
138 | case 'js': |
139 | if (str_starts_with($mimeType, 'text/')) { |
140 | return 'text/javascript'; |
141 | } |
142 | break; |
143 | case 'css': |
144 | // for css files mime type can be 'text/plain' due to bug in finfo |
145 | // (see more: https://bugs.php.net/bug.php?id=53035) |
146 | if (str_starts_with($mimeType, 'text/')) { |
147 | return 'text/css'; |
148 | } |
149 | break; |
150 | case 'svg': |
151 | case 'svgz': |
152 | // when there are more than one image in svg file - finfo recognizes it as `image/svg`, while it |
153 | // should be `image/svg+xml` or at least `text/plain` for a previous hack to work |
154 | if (in_array($mimeType, self::ALLOWED_SVGZ_MIMETYPES, true)) { |
155 | return tao_helpers_File::MIME_SVG; |
156 | } |
157 | break; |
158 | case 'mp3': |
159 | return 'audio/mpeg'; |
160 | } |
161 | |
162 | return $mimeType; |
163 | } |
164 | } |