Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (210)

Classes/Middleware/Embedded3dViewer.php (2 issues)

1
<?php
2
3
namespace Kitodo\Dlf\Middleware;
4
5
/**
6
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
7
 *
8
 * This file is part of the Kitodo and TYPO3 projects.
9
 *
10
 * @license GNU General Public License version 3 or later.
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 */
14
15
use Psr\Http\Message\ResponseInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Http\Server\MiddlewareInterface;
18
use Psr\Http\Server\RequestHandlerInterface;
19
use Psr\Log\LoggerAwareInterface;
20
use Psr\Log\LoggerAwareTrait;
21
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
22
use TYPO3\CMS\Core\Configuration\Loader\YamlFileLoader;
23
use TYPO3\CMS\Core\Core\Environment;
24
use TYPO3\CMS\Core\Exception;
25
use TYPO3\CMS\Core\Http\HtmlResponse;
26
use TYPO3\CMS\Core\Log\LogManager;
27
use TYPO3\CMS\Core\Resource\Folder;
28
use TYPO3\CMS\Core\Resource\ResourceFactory;
29
use TYPO3\CMS\Core\Resource\StorageRepository;
30
use TYPO3\CMS\Core\Utility\GeneralUtility;
31
use TYPO3\CMS\Core\Utility\PathUtility;
32
use TYPO3\CMS\Frontend\Controller\ErrorController;
33
34
/**
35
 * Middleware for embedding custom 3D Viewer implementation of the 'dlf' extension.
36
 *
37
 * @package TYPO3
38
 * @subpackage dlf
39
 * @access public
40
 */
41
class Embedded3dViewer implements LoggerAwareInterface, MiddlewareInterface
42
{
43
    use LoggerAwareTrait;
44
45
    const VIEWER_FOLDER = "dlf_3d_viewers";
46
    const VIEWER_CONFIG_YML = "dlf-3d-viewer.yml";
47
    const EXT_KEY = "dlf";
48
49
    /**
50
     * The main method of the middleware.
51
     *
52
     * @access public
53
     *
54
     * @param ServerRequestInterface $request for processing
55
     * @param RequestHandlerInterface $handler for processing
56
     *
57
     * @return ResponseInterface
58
     */
59
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
60
    {
61
        $response = $handler->handle($request);
62
        // parameters are sent by POST --> use getParsedBody() instead of getQueryParams()
63
        $parameters = $request->getQueryParams();
64
        // Return if not this middleware
65
        if (!isset($parameters['middleware']) || ($parameters['middleware'] != 'dlf/embedded3dviewer')) {
66
            return $response;
67
        }
68
69
        $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
70
71
        if (empty($parameters['model'])) {
72
            return $this->warningResponse('Model url is missing.', $request);
73
        }
74
75
        $modelInfo = PathUtility::pathinfo($parameters['model']);
76
        $modelFormat = $modelInfo["extension"];
77
        if (empty($modelFormat)) {
78
            return $this->warningResponse('Model path "' . $parameters['model'] . '" has no extension format', $request);
79
        }
80
81
        if (empty($parameters['viewer'])) {
82
            // determine viewer from extension configuration
83
            $viewer = $this->getViewerByExtensionConfiguration($modelFormat);
84
        } else {
85
            $viewer = $parameters['viewer'];
86
        }
87
88
        if (empty($viewer)) {
89
            return $this->renderDefaultViewer($parameters['model']);
90
        }
91
92
        /** @var StorageRepository $storageRepository */
93
        $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
94
        $defaultStorage = $storageRepository->getDefaultStorage();
95
96
        if (!$defaultStorage->hasFolder(self::VIEWER_FOLDER)) {
97
            return $this->errorResponse('Required folder "' . self::VIEWER_FOLDER . '" was not found in the default storage "' . $defaultStorage->getName() . '"', $request);
98
        }
99
100
        $viewerModules = $defaultStorage->getFolder(self::VIEWER_FOLDER);
101
        if (!$viewerModules->hasFolder($viewer)) {
102
            return $this->errorResponse('Viewer folder "' . $viewer . '" was not found under the folder "' . self::VIEWER_FOLDER . '"', $request);
103
        }
104
105
        $viewerFolder = $viewerModules->getSubfolder($viewer);
106
        if (!$viewerFolder->hasFile(self::VIEWER_CONFIG_YML)) {
107
            return $this->errorResponse('Viewer folder "' . $viewer . '" does not contain a file named "' . self::VIEWER_CONFIG_YML . '"', $request);
108
        }
109
110
        /** @var YamlFileLoader $yamlFileLoader */
111
        $yamlFileLoader = GeneralUtility::makeInstance(YamlFileLoader::class);
112
        $viewerConfigPath = $defaultStorage->getName() . "/" . self::VIEWER_FOLDER . "/" . $viewer . "/";
113
        $config = $yamlFileLoader->load($viewerConfigPath . self::VIEWER_CONFIG_YML)["viewer"];
114
115
        if (!isset($config["supportedModelFormats"]) || empty($config["supportedModelFormats"])) {
116
            return $this->errorResponse('Required key "supportedModelFormats" does not exist in the file "' . self::VIEWER_CONFIG_YML . '" of viewer "' . $viewer . '" or has no value', $request);
117
        }
118
119
        if (array_search(strtolower($modelFormat), array_map('strtolower', $config["supportedModelFormats"])) === false) {
120
            return $this->warningResponse('Viewer "' . $viewer . '" does not support the model format "' . $modelFormat . '"', $request);
121
        }
122
123
        $html = $this->getViewerHtml($config, $viewerConfigPath, $viewerFolder, $parameters['model'], $modelInfo);
0 ignored issues
show
$modelInfo of type string is incompatible with the type array expected by parameter $modelInfo of Kitodo\Dlf\Middleware\Em...Viewer::getViewerHtml(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

123
        $html = $this->getViewerHtml($config, $viewerConfigPath, $viewerFolder, $parameters['model'], /** @scrutinizer ignore-type */ $modelInfo);
Loading history...
124
        return new HtmlResponse($html);
125
    }
126
127
    /**
128
     * Build the error response.
129
     *
130
     * Logs the given message as error and return internal error response.
131
     *
132
     * @param string $message
133
     * @param ServerRequestInterface $request
134
     * @return ResponseInterface
135
     * @throws \TYPO3\CMS\Core\Error\Http\InternalServerErrorException
136
     */
137
    public function errorResponse(string $message, ServerRequestInterface $request): ResponseInterface
138
    {
139
        /** @var ErrorController $errorController */
140
        $errorController = GeneralUtility::makeInstance(ErrorController::class);
141
        $this->logger->error($message);
142
        return $errorController->internalErrorAction($request, $message);
143
    }
144
145
    /**
146
     * Build the warning response.
147
     *
148
     * Logs the given message as warning and return page not found response.
149
     *
150
     * @param string $message
151
     * @param ServerRequestInterface $request
152
     * @return ResponseInterface
153
     * @throws \TYPO3\CMS\Core\Error\Http\PageNotFoundException
154
     */
155
    public function warningResponse(string $message, ServerRequestInterface $request): ResponseInterface
156
    {
157
        /** @var ErrorController $errorController */
158
        $errorController = GeneralUtility::makeInstance(ErrorController::class);
159
        $this->logger->warning($message);
160
        return $errorController->pageNotFoundAction($request, $message);
161
    }
162
163
    /**
164
     * Determines the viewer based on the extension configuration and the given model format.
165
     *
166
     * @param $modelFormat string The model format
167
     * @return string The 3D viewer
168
     */
169
    private function getViewerByExtensionConfiguration(string $modelFormat): string
170
    {
171
        try {
172
            $extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get(self::EXT_KEY, '3dviewer');
173
            $viewerModelFormatMappings = explode(";", $extConf['viewerModelFormatMapping']);
174
            foreach ($viewerModelFormatMappings as $viewerModelFormatMapping) {
175
                $explodedViewerModelMapping = explode(":", $viewerModelFormatMapping);
176
                if (count($explodedViewerModelMapping) == 2) {
177
                    $viewer = trim($explodedViewerModelMapping[0]);
178
                    $viewerModelFormats = array_map('trim', explode(",", $explodedViewerModelMapping[1]));
179
                    if (in_array($modelFormat, $viewerModelFormats)) {
180
                        return $viewer;
181
                    }
182
                }
183
            }
184
        } catch (Exception $exception) {
185
            $this->logger->debug($exception->getMessage());
186
        }
187
        return $extConf['defaultViewer'] ?? "";
188
    }
189
190
    /**
191
     * @param string $viewerUrl
192
     * @param string $html
193
     * @param string $modelUrl
194
     * @param array $modelInfo
195
     * @return string
196
     */
197
    public function replacePlaceholders(string $viewerUrl, string $html, $modelUrl, array $modelInfo): string
198
    {
199
        $html = str_replace("{{viewerPath}}", $viewerUrl, $html);
200
        $html = str_replace("{{modelUrl}}", $modelUrl, $html);
201
        $html = str_replace("{{modelPath}}", $modelInfo["dirname"], $html);
202
        return str_replace("{{modelResource}}", $modelInfo["basename"], $html);
203
    }
204
205
    /**
206
     * @param $model
207
     * @return HtmlResponse
208
     * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
209
     */
210
    public function renderDefaultViewer($model): HtmlResponse
211
    {
212
        /** @var ResourceFactory $resourceFactory */
213
        $resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
214
        $html = $resourceFactory->retrieveFileOrFolderObject('EXT:dlf/Resources/Public/Html/Embedded3dViewerStandalone.html')->getContents();
0 ignored issues
show
The method getContents() does not exist on TYPO3\CMS\Core\Resource\Folder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

214
        $html = $resourceFactory->retrieveFileOrFolderObject('EXT:dlf/Resources/Public/Html/Embedded3dViewerStandalone.html')->/** @scrutinizer ignore-call */ getContents();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
215
        $file = $resourceFactory->retrieveFileOrFolderObject('EXT:dlf/Resources/Public/JavaScript/Embedded3dViewer/model-viewer-3.5.0.min.js');
216
        $html = str_replace('{{modelViewerJS}}', $file->getPublicUrl(), $html);
217
        $html = str_replace("{{modelUrl}}", $model, $html);
218
        return new HtmlResponse($html);
219
    }
220
221
    /**
222
     * @param array $config
223
     * @param string $viewerConfigPath
224
     * @param Folder $viewerFolder
225
     * @param string $modelUrl
226
     * @param array $modelInfo
227
     * @return string
228
     */
229
    public function getViewerHtml(array $config, string $viewerConfigPath, Folder $viewerFolder, string $modelUrl, array $modelInfo): string
230
    {
231
        $htmlFile = "index.html";
232
        if (isset($config["base"]) && !empty($config["base"])) {
233
            $htmlFile = $config["base"];
234
        }
235
236
        $viewerUrl = $viewerConfigPath;
237
        if (isset($config["url"]) && !empty($config["url"])) {
238
            $viewerUrl = rtrim($config["url"]);
239
        }
240
241
        $html = $viewerFolder->getFile($htmlFile)->getContents();
242
        return $this->replacePlaceholders($viewerUrl, $html, $modelUrl, $modelInfo);
243
    }
244
}
245