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.
Completed
Push — master ( 3f7054...c9d2a6 )
by Sebastian
18s queued 13s
created

Classes/Plugin/PageView.php (1 issue)

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\Plugin;
14
15
use Kitodo\Dlf\Common\Helper;
16
use Kitodo\Dlf\Common\IiifManifest;
17
use Ubl\Iiif\Presentation\Common\Model\Resources\ManifestInterface;
18
use Ubl\Iiif\Presentation\Common\Vocabulary\Motivation;
19
20
/**
21
 * Plugin 'Page View' for the 'dlf' extension
22
 *
23
 * @author Sebastian Meyer <[email protected]>
24
 * @package TYPO3
25
 * @subpackage dlf
26
 * @access public
27
 */
28
class PageView extends \Kitodo\Dlf\Common\AbstractPlugin
29
{
30
    public $scriptRelPath = 'Classes/Plugin/PageView.php';
31
32
    /**
33
     * Holds the controls to add to the map
34
     *
35
     * @var array
36
     * @access protected
37
     */
38
    protected $controls = [];
39
40
    /**
41
     * Holds the current images' URLs and MIME types
42
     *
43
     * @var array
44
     * @access protected
45
     */
46
    protected $images = [];
47
48
    /**
49
     * Holds the current fulltexts' URLs
50
     *
51
     * @var array
52
     * @access protected
53
     */
54
    protected $fulltexts = [];
55
56
    /**
57
     * Holds the current AnnotationLists / AnnotationPages
58
     *
59
     * @var array
60
     * @access protected
61
     */
62
    protected $annotationContainers = [];
63
64
    /**
65
     * Adds Viewer javascript
66
     *
67
     * @access protected
68
     *
69
     * @return string The output string for the ###JAVASCRIPT### template marker
70
     */
71
    protected function addViewerJS()
72
    {
73
        $markerArray = '';
74
        // CSS files.
75
        $cssFiles = [
76
            'Resources/Public/Javascript/OpenLayers/ol3.css'
77
        ];
78
        // Javascript files.
79
        $jsFiles = [
80
            // OpenLayers
81
            'Resources/Public/Javascript/OpenLayers/glif.min.js',
82
            'Resources/Public/Javascript/OpenLayers/ol3-dlf.js',
83
            // Viewer
84
            'Resources/Public/Javascript/PageView/Utility.js',
85
            'Resources/Public/Javascript/PageView/OL3.js',
86
            'Resources/Public/Javascript/PageView/OL3Styles.js',
87
            'Resources/Public/Javascript/PageView/OL3Sources.js',
88
            'Resources/Public/Javascript/PageView/AltoParser.js',
89
            'Resources/Public/Javascript/PageView/AnnotationParser.js',
90
            'Resources/Public/Javascript/PageView/AnnotationControl.js',
91
            'Resources/Public/Javascript/PageView/ImageManipulationControl.js',
92
            'Resources/Public/Javascript/PageView/FulltextDownloadControl.js',
93
            'Resources/Public/Javascript/PageView/FulltextControl.js',
94
            'Resources/Public/Javascript/PageView/FullTextUtility.js',
95
            'Resources/Public/Javascript/PageView/PageView.js'
96
        ];
97
        // Viewer configuration.
98
        $viewerConfiguration = '
99
            $(document).ready(function() {
100
                if (dlfUtils.exists(dlfViewer)) {
101
                    tx_dlf_viewer = new dlfViewer({
102
                        controls: ["' . implode('", "', $this->controls) . '"],
103
                        div: "' . $this->conf['elementId'] . '",
104
                        images: ' . json_encode($this->images) . ',
105
                        fulltexts: ' . json_encode($this->fulltexts) . ',
106
                        annotationContainers: ' . json_encode($this->annotationContainers) . ',
107
                        useInternalProxy: ' . ($this->conf['useInternalProxy'] ? 1 : 0) . '
108
                    });
109
                }
110
            });
111
        ';
112
        // Add Javascript to page footer if not configured otherwise.
113
        if (empty($this->conf['addJStoBody'])) {
114
            $pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class);
115
            foreach ($cssFiles as $cssFile) {
116
                $pageRenderer->addCssFile(\TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($this->extKey)) . $cssFile);
117
            }
118
            foreach ($jsFiles as $jsFile) {
119
                $pageRenderer->addJsFooterFile(\TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($this->extKey)) . $jsFile);
120
            }
121
            $pageRenderer->addJsFooterInlineCode('kitodo-pageview-configuration', $viewerConfiguration);
122
        } else {
123
            foreach ($jsFiles as $jsFile) {
124
                $markerArray .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($this->extKey)) . $jsFile . '"></script>' . "\n";
125
            }
126
            $markerArray .= '
127
                <script type="text/javascript">
128
                /*<![CDATA[*/
129
                /*kitodo-pageview-configuration*/
130
                ' . $viewerConfiguration . '
131
                /*]]>*/
132
                </script>';
133
        }
134
        return $markerArray;
135
    }
136
137
    /**
138
     * Adds pageview interaction (crop, magnifier and rotation)
139
     *
140
     * @access protected
141
     *
142
     * @return array Marker array
143
     */
144
    protected function addInteraction()
145
    {
146
        $markerArray = [];
147
        if ($this->piVars['id']) {
148
            if ($this->conf['crop']) {
149
                $markerArray['###EDITBUTTON###'] = '<a href="javascript: tx_dlf_viewer.activateSelection();" title="' . htmlspecialchars($this->pi_getLL('editMode', '')) . '">' . htmlspecialchars($this->pi_getLL('editMode', '')) . '</a>';
150
                $markerArray['###EDITREMOVE###'] = '<a href="javascript: tx_dlf_viewer.resetCropSelection();" title="' . htmlspecialchars($this->pi_getLL('editRemove', '')) . '">' . htmlspecialchars($this->pi_getLL('editRemove', '')) . '</a>';
151
            } else {
152
                $markerArray['###EDITBUTTON###'] = '';
153
                $markerArray['###EDITREMOVE###'] = '';
154
            }
155
            if ($this->conf['magnifier']) {
156
                $markerArray['###MAGNIFIER###'] = '<a href="javascript: tx_dlf_viewer.activateMagnifier();" title="' . htmlspecialchars($this->pi_getLL('magnifier', '')) . '">' . htmlspecialchars($this->pi_getLL('magnifier', '')) . '</a>';
157
            } else {
158
                $markerArray['###MAGNIFIER###'] = '';
159
            }
160
        }
161
        return $markerArray;
162
    }
163
164
    /**
165
     * Adds form to save cropping data to basket
166
     *
167
     * @access protected
168
     *
169
     * @return array Marker array
170
     */
171
    protected function addBasketForm()
172
    {
173
        $markerArray = [];
174
        // Add basket button
175
        if ($this->conf['basketButton'] && $this->conf['targetBasket'] && $this->piVars['id']) {
176
            $label = htmlspecialchars($this->pi_getLL('addBasket', ''));
177
            $params = [
178
                'id' => $this->piVars['id'],
179
                'addToBasket' => true
180
            ];
181
            if (empty($this->piVars['page'])) {
182
                $params['page'] = 1;
183
            }
184
            $basketConf = [
185
                'parameter' => $this->conf['targetBasket'],
186
                'forceAbsoluteUrl' => !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0,
187
                'forceAbsoluteUrl.' => ['scheme' => !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http'],
188
                'additionalParams' => \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($this->prefixId, $params, '', true, false),
189
                'title' => $label
190
            ];
191
            $output = '<form id="addToBasketForm" action="' . $this->cObj->typoLink_URL($basketConf) . '" method="post">';
192
            $output .= '<input type="hidden" name="tx_dlf[startpage]" id="startpage" value="' . htmlspecialchars($this->piVars['page']) . '">';
193
            $output .= '<input type="hidden" name="tx_dlf[endpage]" id="endpage" value="' . htmlspecialchars($this->piVars['page']) . '">';
194
            $output .= '<input type="hidden" name="tx_dlf[startX]" id="startX">';
195
            $output .= '<input type="hidden" name="tx_dlf[startY]" id="startY">';
196
            $output .= '<input type="hidden" name="tx_dlf[endX]" id="endX">';
197
            $output .= '<input type="hidden" name="tx_dlf[endY]" id="endY">';
198
            $output .= '<input type="hidden" name="tx_dlf[rotation]" id="rotation">';
199
            $output .= '<button id="submitBasketForm" onclick="this.form.submit()">' . $label . '</button>';
200
            $output .= '</form>';
201
            $output .= '<script>';
202
            $output .= '$(document).ready(function() { $("#submitBasketForm").click(function() { $("#addToBasketForm").submit(); }); });';
203
            $output .= '</script>';
204
            $markerArray['###BASKETBUTTON###'] = $output;
205
        } else {
206
            $markerArray['###BASKETBUTTON###'] = '';
207
        }
208
        return $markerArray;
209
    }
210
211
    /**
212
     * Get image's URL and MIME type
213
     *
214
     * @access protected
215
     *
216
     * @param int $page: Page number
217
     *
218
     * @return array URL and MIME type of image file
219
     */
220
    protected function getImage($page)
221
    {
222
        $image = [];
223
        // Get @USE value of METS fileGrp.
224
        $fileGrps = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->conf['fileGrps']);
225
        while ($fileGrp = @array_pop($fileGrps)) {
226
            // Get image link.
227
            if (!empty($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$fileGrp])) {
228
                $image['url'] = $this->doc->getFileLocation($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$fileGrp]);
229
                if ($this->conf['useInternalProxy']) {
230
                    // Configure @action URL for form.
231
                    $linkConf = [
232
                        'parameter' => $GLOBALS['TSFE']->id,
233
                        'forceAbsoluteUrl' => !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0,
234
                        'forceAbsoluteUrl.' => ['scheme' => !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http'],
235
                        'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($image['url']),
236
                    ];
237
                    $image['url'] = $this->cObj->typoLink_URL($linkConf);
238
                }
239
                $image['mimetype'] = $this->doc->getFileMimeType($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$fileGrp]);
240
                break;
241
            } else {
242
                Helper::devLog('File not found in fileGrp "' . $fileGrp . '"', DEVLOG_SEVERITY_WARNING);
243
            }
244
        }
245
        return $image;
246
    }
247
248
    /**
249
     * Get fulltext URL and MIME type
250
     *
251
     * @access protected
252
     *
253
     * @param int $page: Page number
254
     *
255
     * @return array URL and MIME type of fulltext file
256
     */
257
    protected function getFulltext($page)
258
    {
259
        $fulltext = [];
260
        // Get fulltext link.
261
        if (!empty($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$this->conf['fileGrpFulltext']])) {
262
            $fulltext['url'] = $this->doc->getFileLocation($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$this->conf['fileGrpFulltext']]);
263
            if ($this->conf['useInternalProxy']) {
264
                // Configure @action URL for form.
265
                $linkConf = [
266
                    'parameter' => $GLOBALS['TSFE']->id,
267
                    'forceAbsoluteUrl' => !empty($this->conf['forceAbsoluteUrl']) ? 1 : 0,
268
                    'forceAbsoluteUrl.' => ['scheme' => !empty($this->conf['forceAbsoluteUrl']) && !empty($this->conf['forceAbsoluteUrlHttps']) ? 'https' : 'http'],
269
                    'additionalParams' => '&eID=tx_dlf_pageview_proxy&url=' . urlencode($fulltext['url']),
270
                ];
271
                $fulltext['url'] = $this->cObj->typoLink_URL($linkConf);
272
            }
273
            $fulltext['mimetype'] = $this->doc->getFileMimeType($this->doc->physicalStructureInfo[$this->doc->physicalStructure[$page]]['files'][$this->conf['fileGrpFulltext']]);
274
        } else {
275
            Helper::devLog('File not found in fileGrp "' . $this->conf['fileGrpFulltext'] . '"', DEVLOG_SEVERITY_WARNING);
276
        }
277
        return $fulltext;
278
    }
279
280
    /**
281
     * Get all AnnotationPages / AnnotationLists that contain text Annotations with motivation "painting"
282
     *
283
     * @access protected
284
     *
285
     * @param int $page: Page number
286
     * @return array An array containing the IRIs of the AnnotationLists / AnnotationPages as well as
287
     *               some information about the canvas.
288
     */
289
    protected function getAnnotationContainers($page)
290
    {
291
        if ($this->doc instanceof IiifManifest) {
292
            $canvasId = $this->doc->physicalStructure[$page];
293
            $iiif = $this->doc->getIiif();
294
            if ($iiif instanceof ManifestInterface) {
295
                $canvas = $iiif->getContainedResourceById($canvasId);
296
                /* @var $canvas \Ubl\Iiif\Presentation\Common\Model\Resources\CanvasInterface */
297
                if ($canvas != null && !empty($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING))) {
298
                    $annotationContainers = [];
299
                    /*
300
                     *  TODO Analyzing the annotations on the server side requires loading the annotation lists / pages
301
                     *  just to determine wether they contain text annotations for painting. This will take time and lead to a bad user experience.
302
                     *  It would be better to link every annotation and analyze the data on the client side.
303
                     *
304
                     *  On the other hand, server connections are potentially better than client connections. Downloading annotation lists
305
                     */
306
                    foreach ($canvas->getPossibleTextAnnotationContainers(Motivation::PAINTING) as $annotationContainer) {
307
                        if (($textAnnotations = $annotationContainer->getTextAnnotations(Motivation::PAINTING)) != null) {
308
                            foreach ($textAnnotations as $annotation) {
309
                                if (
310
                                    $annotation->getBody()->getFormat() == 'text/plain'
311
                                    && $annotation->getBody()->getChars() != null
312
                                ) {
313
                                    $annotationListData = [];
314
                                    $annotationListData['uri'] = $annotationContainer->getId();
315
                                    $annotationListData['label'] = $annotationContainer->getLabelForDisplay();
316
                                    $annotationContainers[] = $annotationListData;
317
                                    break;
318
                                }
319
                            }
320
                        }
321
                    }
322
                    $result = [
323
                        'canvas' => [
324
                            'id' => $canvas->getId(),
325
                            'width' => $canvas->getWidth(),
326
                            'height' => $canvas->getHeight(),
327
                        ],
328
                        'annotationContainers' => $annotationContainers
329
                    ];
330
                    return $result;
331
                }
332
            }
333
        }
334
        return [];
335
    }
336
337
    /**
338
     * The main method of the PlugIn
339
     *
340
     * @access public
341
     *
342
     * @param string $content: The PlugIn content
343
     * @param array $conf: The PlugIn configuration
344
     *
345
     * @return string The content that is displayed on the website
346
     */
347
    public function main($content, $conf)
348
    {
349
        $this->init($conf);
350
        // Load current document.
351
        $this->loadDocument();
352
        if (
353
            $this->doc === null
354
            || $this->doc->numPages < 1
355
        ) {
356
            // Quit without doing anything if required variables are not set.
357
            return $content;
358
        } else {
359
            if (!empty($this->piVars['logicalPage'])) {
360
                $this->piVars['page'] = $this->doc->getPhysicalPage($this->piVars['logicalPage']);
0 ignored issues
show
Bug Best Practice introduced by
The property piVars does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
361
                // The logical page parameter should not appear again
362
                unset($this->piVars['logicalPage']);
363
            }
364
            // Set default values if not set.
365
            // $this->piVars['page'] may be integer or string (physical structure @ID)
366
            if ((int) $this->piVars['page'] > 0 || empty($this->piVars['page'])) {
367
                $this->piVars['page'] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange((int) $this->piVars['page'], 1, $this->doc->numPages, 1);
368
            } else {
369
                $this->piVars['page'] = array_search($this->piVars['page'], $this->doc->physicalStructure);
370
            }
371
            $this->piVars['double'] = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->piVars['double'], 0, 1, 0);
372
        }
373
        // Load template file.
374
        $this->getTemplate();
375
        // Get image data.
376
        $this->images[0] = $this->getImage($this->piVars['page']);
377
        $this->fulltexts[0] = $this->getFulltext($this->piVars['page']);
378
        $this->annotationContainers[0] = $this->getAnnotationContainers($this->piVars['page']);
379
        if ($this->piVars['double'] && $this->piVars['page'] < $this->doc->numPages) {
380
            $this->images[1] = $this->getImage($this->piVars['page'] + 1);
381
            $this->fulltexts[1] = $this->getFulltext($this->piVars['page'] + 1);
382
            $this->annotationContainers[1] = $this->getAnnotationContainers($this->piVars['page'] + 1);
383
        }
384
        // Get the controls for the map.
385
        $this->controls = explode(',', $this->conf['features']);
386
        // Fill in the template markers.
387
        $markerArray = array_merge($this->addInteraction(), $this->addBasketForm());
388
        $markerArray['###JAVASCRIPT###'] = $this->addViewerJS();
389
        $content .= $this->templateService->substituteMarkerArray($this->template, $markerArray);
390
        return $this->pi_wrapInBaseClass($content);
391
    }
392
}
393