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