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.
Passed
Pull Request — master (#818)
by
unknown
12:19 queued 08:29
created

MediaPlayerController   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 80
c 1
b 0
f 0
dl 0
loc 183
rs 10
wmc 30

6 Methods

Rating   Name   Duplication   Size   Complexity  
A findFiles() 0 13 3
A addPlayerJS() 0 14 1
B mainAction() 0 37 8
B getVideoInfo() 0 50 9
A recurseChapters() 0 13 4
A isMediaMime() 0 8 5
1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Controller;
14
15
use Kitodo\Dlf\Common\Doc;
16
use TYPO3\CMS\Core\Page\PageRenderer;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\Core\Utility\MathUtility;
19
20
/**
21
 * Plugin MediaPlayer for the 'dlf' extension
22
 *
23
 * @author Kajetan Dvoracek <[email protected]>
24
 * @package TYPO3
25
 * @subpackage dlf
26
 * @access public
27
 */
28
class MediaPlayerController extends AbstractController
29
{
30
    /**
31
     * The main method of the PlugIn
32
     *
33
     * @access public
34
     *
35
     * @param string $content: The PlugIn content
36
     * @param array $conf: The PlugIn configuration
37
     *
38
     * @return string The content that is displayed on the website
39
     */
40
    public function mainAction()
41
    {
42
        // Load current document.
43
        $this->loadDocument($this->requestData);
44
        if (
45
            $this->document === null
46
            || $this->document->getDoc() === null
47
            || $this->document->getDoc()->numPages < 1
48
        ) {
49
            // Quit without doing anything if required variables are not set.
50
            return;
51
        } else {
52
            if (!empty($this->requestData['logicalPage'])) {
53
                $this->requestData['page'] = $this->document->getDoc()->getPhysicalPage($this->requestData['logicalPage']);
54
                // The logical page parameter should not appear again
55
                unset($this->requestData['logicalPage']);
56
            }
57
            // Set default values if not set.
58
            // $this->requestData['page'] may be integer or string (physical structure @ID)
59
            if ((int) $this->requestData['page'] > 0 || empty($this->requestData['page'])) {
60
                $this->requestData['page'] = MathUtility::forceIntegerInRange((int) $this->requestData['page'], 1, $this->document->getDoc()->numPages, 1);
61
            } else {
62
                $this->requestData['page'] = array_search($this->requestData['page'], $this->document->getDoc()->physicalStructure);
63
            }
64
            $this->requestData['double'] = MathUtility::forceIntegerInRange($this->requestData['double'], 0, 1, 0);
65
        }
66
67
        $doc = $this->document->getDoc();
68
        $pageNo = $this->requestData['page'];
69
        $video = $this->getVideoInfo($doc, $pageNo);
70
        if ($video === null) {
71
            return;
72
        }
73
74
        $this->addPlayerJS();
75
76
        $this->view->assign('video', $video);
77
    }
78
79
    /**
80
     * Build video info to be passed to the player template.
81
     *
82
     * @return ?array The video data, or `null` if no video source is found
83
     */
84
    protected function getVideoInfo(Doc $doc, int $pageNo): ?array
85
    {
86
        $videoFileGrps = GeneralUtility::trimExplode(',', $this->extConf['fileGrpVideo']);
87
        $mainVideoFileGrp = $videoFileGrps[0] ?? '';
88
89
        $thumbFileGroups = GeneralUtility::trimExplode(',', $this->extConf['fileGrpThumbs']);
90
91
        $initialMode = 'audio';
92
93
        // Collect video file source URLs
94
        // TODO: This is for multiple sources (MPD, HLS, MP3, ...) - revisit, make sure it's ordered by preference!
95
        $videoSources = [];
96
        $videoFiles = $this->findFiles($doc, $pageNo, $videoFileGrps);
97
        foreach ($videoFiles as $videoFile) {
98
            $mimeType = $doc->getFileMimeType($videoFile['fileId']);
99
            if ($this->isMediaMime($mimeType)) {
100
                $url = $doc->getFileLocation($videoFile['fileId']);
101
                $videoSources[] = compact('mimeType', 'url');
102
103
                // TODO: Better guess of initial mode?
104
                //       Perhaps we could look for VIDEOMD/AUDIOMD in METS
105
                if ($videoFile['fileGrp'] === $mainVideoFileGrp || strpos($mimeType, 'video/') === 0) {
106
                    $initialMode = 'video';
107
                }
108
            }
109
        }
110
        if (empty($videoSources)) {
111
            return null;
112
        }
113
114
        // List all chapters for chapter markers
115
        $videoChapters = [];
116
        foreach ($doc->tableOfContents as $entry) {
117
            $this->recurseChapters($entry, $videoChapters);
118
        }
119
120
        // Get additional video URLs
121
        $videoUrl = [];
122
        $thumbFiles = $this->findFiles($doc, 0, $thumbFileGroups);
123
        if (!empty($thumbFiles)) {
124
            $videoUrl['poster'] = urldecode($doc->getFileLocation($thumbFiles[0]['fileId']));
125
        }
126
127
        return [
128
            'start' => $videoChapters[$pageNo - 1]['timecode'] ?: '',
129
            'mode' => $initialMode,
130
            'chapters' => $videoChapters,
131
            'metadata' => $doc->getTitledata($this->settings['storagePid']),
132
            'sources' => $videoSources,
133
            'url' => $videoUrl,
134
        ];
135
    }
136
137
    /**
138
     * Find files of the given file groups that are referenced on a page.
139
     *
140
     * @param Doc $doc
141
     * @param int $pageNo
142
     * @param string[] $fileGrps
143
     * @return string[]
144
     */
145
    protected function findFiles(Doc $doc, int $pageNo, array $fileGrps): array
146
    {
147
        $pagePhysKey = $doc->physicalStructure[$pageNo];
148
        $pageFiles = $doc->physicalStructureInfo[$pagePhysKey]['all_files'] ?? [];
149
        $filesInGrp = array_intersect_key($pageFiles, array_flip($fileGrps));
150
151
        $result = [];
152
        foreach ($filesInGrp as $fileGrp => $fileIds) {
153
            foreach ($fileIds as $fileId) {
154
                $result[] = compact('fileGrp', 'fileId');
155
            }
156
        }
157
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns an array which contains values of type array which are incompatible with the documented value type string.
Loading history...
158
    }
159
160
    /**
161
     * Recursively push chapters in given logical structure to $outChapters.
162
     */
163
    protected function recurseChapters(array $logInfo, array &$outChapters)
164
    {
165
        if ($logInfo['type'] === 'segment' && isset($logInfo['videoChapter'])) {
166
            $outChapters[] = [
167
                'fileId' => $logInfo['videoChapter']['fileId'],
168
                'pageNo' => $logInfo['points'],
169
                'title' => $logInfo['label'] ?? '',
170
                'timecode' => $logInfo['videoChapter']['timecode'],
171
            ];
172
        }
173
174
        foreach ($logInfo['children'] ?? [] as $child) {
175
            $this->recurseChapters($child, $outChapters);
176
        }
177
    }
178
179
    protected function isMediaMime(string $mimeType)
180
    {
181
        return (
182
            strpos($mimeType, 'audio/') === 0
183
            || strpos($mimeType, 'video/') === 0
184
            || $mimeType == 'application/dash+xml'
185
            || $mimeType == 'application/x-mpegurl'
186
            || $mimeType == 'application/vnd.apple.mpegurl'
187
        );
188
    }
189
190
    /**
191
     * Adds Player javascript
192
     *
193
     * @access protected
194
     *
195
     * @return void
196
     */
197
    protected function addPlayerJS()
198
    {
199
        // TODO: TYPO3 v10
200
        // $assetCollector = GeneralUtility::makeInstance(AssetCollector::class);
201
        // $assetCollector->addJavaScript('DlfMediaPlayer.js', 'EXT:dlf/Resources/Public/Javascript/DlfMediaPlayer.js');
202
        // $assetCollector->addStyleSheet('DlfMediaPlayer.css', 'EXT:dlf/Resources/Public/Css/DlfMediaPlayerStyles.css');
203
204
        // TODO: Move to TypoScript
205
        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
206
        $pageRenderer->addCssFile('EXT:dlf/Resources/Public/Css/DlfMediaPlayer.css');
207
        $pageRenderer->addCssFile('EXT:dlf/Resources/Public/Css/DlfMediaVendor.css', 'stylesheet', 'all', '', true, false, '', /* excludeFromConcatenation= */true);
208
        $pageRenderer->addCssFile('EXT:dlf/Resources/Public/Css/DlfMediaPlayerStyles.css');
209
        $pageRenderer->addJsFooterFile('EXT:dlf/Resources/Public/Javascript/DlfMediaPlayer.js');
210
        $pageRenderer->addJsFooterFile('EXT:dlf/Resources/Public/Javascript/DlfMediaVendor.js', 'text/javascript', true, false, '', /* excludeFromConcatenation= */true);
211
    }
212
}
213