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
Push — master ( 6f9851...89efac )
by
unknown
03:54
created

MetadataController::getMetadataForIds()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 10
c 2
b 0
f 0
nc 10
nop 2
dl 0
loc 15
rs 9.6111
1
<?php
2
/**
3
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
4
 *
5
 * This file is part of the Kitodo and TYPO3 projects.
6
 *
7
 * @license GNU General Public License version 3 or later.
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace Kitodo\Dlf\Controller;
13
14
use Kitodo\Dlf\Common\Doc;
15
use Kitodo\Dlf\Common\Helper;
16
use Kitodo\Dlf\Common\IiifManifest;
17
use Kitodo\Dlf\Domain\Model\Collection;
18
use Kitodo\Dlf\Domain\Model\Metadata;
19
use Kitodo\Dlf\Domain\Repository\CollectionRepository;
20
use Kitodo\Dlf\Domain\Repository\MetadataRepository;
21
use Kitodo\Dlf\Domain\Repository\StructureRepository;
22
use Ubl\Iiif\Context\IRI;
23
24
/**
25
 * Controller class for the plugin 'Metadata'.
26
 *
27
 * @author Sebastian Meyer <[email protected]>
28
 * @package TYPO3
29
 * @subpackage dlf
30
 * @access public
31
 */
32
class MetadataController extends AbstractController
33
{
34
    /**
35
     * @var Doc
36
     */
37
    private $doc;
38
39
    /**
40
     * @var CollectionRepository
41
     */
42
    protected $collectionRepository;
43
44
    /**
45
     * @param CollectionRepository $collectionRepository
46
     */
47
    public function injectCollectionRepository(CollectionRepository $collectionRepository)
48
    {
49
        $this->collectionRepository = $collectionRepository;
50
    }
51
52
    /**
53
     * @var MetadataRepository
54
     */
55
    protected $metadataRepository;
56
57
    /**
58
     * @param MetadataRepository $metadataRepository
59
     */
60
    public function injectMetadataRepository(MetadataRepository $metadataRepository)
61
    {
62
        $this->metadataRepository = $metadataRepository;
63
    }
64
65
    /**
66
     * @var StructureRepository
67
     */
68
    protected $structureRepository;
69
70
    /**
71
     * @param StructureRepository $structureRepository
72
     */
73
    public function injectStructureRepository(StructureRepository $structureRepository)
74
    {
75
        $this->structureRepository = $structureRepository;
76
    }
77
78
    /**
79
     * @return string|void
80
     */
81
    public function mainAction()
82
    {
83
        $this->cObj = $this->configurationManager->getContentObject();
0 ignored issues
show
Bug Best Practice introduced by
The property cObj does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
84
85
        // Load current document.
86
        $this->loadDocument();
87
        if ($this->isDocMissing()) {
88
            // Quit without doing anything if required variables are not set.
89
            return '';
90
        } else {
91
            // Set default values if not set.
92
            $this->setDefault('rootline', 0);
93
            $this->setDefault('originalIiifMetadata', 0);
94
            $this->setDefault('displayIiifDescription', 1);
95
            $this->setDefault('displayIiifRights', 1);
96
            $this->setDefault('displayIiifLinks', 1);
97
        }
98
99
        $this->doc = $this->document->getDoc();
100
101
        $useOriginalIiifManifestMetadata = $this->settings['originalIiifMetadata'] == 1 && $this->doc instanceof IiifManifest;
102
        $metadata = $this->getMetadata();
103
        // Get titledata?
104
        if (empty($metadata) || ($this->settings['rootline'] == 1 && $metadata[0]['_id'] != $this->doc->toplevelId)) {
105
            $data = $useOriginalIiifManifestMetadata ? $this->doc->getManifestMetadata($this->doc->toplevelId, $this->settings['storagePid']) : $this->doc->getTitledata($this->settings['storagePid']);
106
            $data['_id'] = $this->doc->toplevelId;
107
            array_unshift($metadata, $data);
108
        }
109
        if (empty($metadata)) {
110
            $this->logger->warning('No metadata found for document with UID ' . $this->document->getUid());
111
            return '';
112
        }
113
        ksort($metadata);
114
115
        $this->printMetadata($metadata, $useOriginalIiifManifestMetadata);
116
    }
117
118
    /**
119
     * Prepares the metadata array for output
120
     *
121
     * @access protected
122
     *
123
     * @param array $metadata: The metadata array
124
     * @param bool $useOriginalIiifManifestMetadata: Output IIIF metadata as simple key/value pairs?
125
     *
126
     * @return string The metadata array ready for output
127
     */
128
    protected function printMetadata(array $metadata, $useOriginalIiifManifestMetadata = false)
129
    {
130
        if ($useOriginalIiifManifestMetadata) {
131
            $iiifData = $this->buildIiifData($metadata);
132
            $this->view->assign('useIiif', true);
133
            $this->view->assign('iiifData', $iiifData);
134
        } else {
135
            // findBySettings also sorts entries by the `sorting` field
136
            $metadataResult = $this->metadataRepository->findBySettings([
137
                'is_listed' => !$this->settings['showFull'],
138
            ]);
139
140
            // Collect raw metadata into an array that will be passed as data to cObj.
141
            // This lets metadata wraps reference (own or foreign) values via TypoScript "field".
142
            $metaCObjData = [];
143
144
            $buildUrl = [];
145
            $externalUrl = [];
146
            $i = 0;
147
            foreach ($metadata as $section) {
148
                $metaCObjData[$i] = [];
149
150
                foreach ($section as $name => $value) {
151
                    // NOTE: Labels are to be escaped in Fluid template
152
153
                    $metaCObjData[$i][$name] = is_array($value)
154
                        ? implode($this->settings['separator'], $value)
155
                        : $value;
156
157
                    if ($name == 'title') {
158
                        // Get title of parent document if needed.
159
                        if (empty(implode('', $value)) && $this->settings['getTitle'] && $this->document->getPartof()) {
160
                            $superiorTitle = Doc::getTitle($this->document->getPartof(), true);
161
                            if (!empty($superiorTitle)) {
162
                                $metadata[$i][$name] = ['[' . $superiorTitle . ']'];
163
                            }
164
                        }
165
                        if (!empty($value)) {
166
                            $metadata[$i][$name][0] = $metadata[$i][$name][0];
167
                            // Link title to pageview.
168
                            if ($this->settings['linkTitle'] && $section['_id']) {
169
                                $details = $this->doc->getLogicalStructure($section['_id']);
170
                                $buildUrl[$i][$name]['buildUrl'] = [
171
                                    'id' => $this->document->getUid(),
172
                                    'page' => (!empty($details['points']) ? intval($details['points']) : 1),
173
                                    'targetPid' => (!empty($this->settings['targetPid']) ? $this->settings['targetPid'] : 0),
174
                                ];
175
                            }
176
                        }
177
                    } elseif (($name == 'author' || $name == 'holder') && !empty($value) && !empty($value[0]['url'])) {
178
                        $externalUrl[$i][$name]['externalUrl'] = $value[0];
179
                    } elseif (($name == 'geonames' || $name == 'wikidata' || $name == 'wikipedia') && !empty($value)) {
180
                        $externalUrl[$i][$name]['externalUrl'] = [
181
                            'name' => $value[0],
182
                            'url' => $value[0]
183
                        ];
184
                    } elseif ($name == 'owner' && empty($value)) {
185
                        // no owner is found by metadata records --> take the one associated to the document
186
                        $library = $this->document->getOwner();
187
                        if ($library) {
188
                            $metadata[$i][$name][0] = $library->getLabel();
189
                        }
190
                    } elseif ($name == 'type' && !empty($value)) {
191
                        // Translate document type.
192
                        $structure = $this->structureRepository->findOneByIndexName($metadata[$i][$name][0]);
0 ignored issues
show
Bug introduced by
The method findOneByIndexName() does not exist on Kitodo\Dlf\Domain\Repository\StructureRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

192
                        /** @scrutinizer ignore-call */ 
193
                        $structure = $this->structureRepository->findOneByIndexName($metadata[$i][$name][0]);
Loading history...
193
                        if ($structure) {
194
                            $metadata[$i][$name][0] = $structure->getLabel();
0 ignored issues
show
Bug introduced by
The method getLabel() does not exist on TYPO3\CMS\Extbase\Persistence\QueryResultInterface. ( Ignorable by Annotation )

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

194
                            /** @scrutinizer ignore-call */ 
195
                            $metadata[$i][$name][0] = $structure->getLabel();

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...
195
                        }
196
                    } elseif ($name == 'collection' && !empty($value)) {
197
                        // Check if collections isn't hidden.
198
                        $j = 0;
199
                        foreach ($value as $entry) {
200
                            $collection = $this->collectionRepository->findOneByIndexName($entry);
0 ignored issues
show
Bug introduced by
The method findOneByIndexName() does not exist on Kitodo\Dlf\Domain\Repository\CollectionRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

200
                            /** @scrutinizer ignore-call */ 
201
                            $collection = $this->collectionRepository->findOneByIndexName($entry);
Loading history...
201
                            if ($collection) {
202
                                $metadata[$i][$name][$j] = $collection->getLabel() ? : '';
203
                                $j++;
204
                            }
205
                        }
206
                    } elseif ($name == 'language' && !empty($value)) {
207
                        // Translate ISO 639 language code.
208
                        foreach ($metadata[$i][$name] as &$langValue) {
209
                            $langValue = Helper::getLanguageName($langValue);
210
                        }
211
                    }
212
213
                    if (is_array($metadata[$i][$name])) {
214
                        $metadata[$i][$name] = array_values(array_filter($metadata[$i][$name], function($metadataValue)
215
                        {
216
                            return !empty($metadataValue);
217
                        }));
218
                    }
219
                }
220
                $i++;
221
            }
222
223
            $this->view->assign('buildUrl', $buildUrl);
224
            $this->view->assign('externalUrl', $externalUrl);
225
            $this->view->assign('documentMetadataSections', $metadata);
226
            $this->view->assign('configMetadata', $metadataResult);
227
            $this->view->assign('separator', $this->settings['separator']);
228
            $this->view->assign('metaCObjData', $metaCObjData);
229
        }
230
    }
231
232
    /**
233
     * Builds the IIIF data array from metadata array
234
     *
235
     * @access private
236
     *
237
     * @param array $metadata The metadata array
238
     *
239
     * @return array The IIIF data array ready for output
240
     */
241
    private function buildIiifData(array $metadata): array
242
    {
243
        $iiifData = [];
244
245
        foreach ($metadata as $row) {
246
            foreach ($row as $key => $group) {
247
                if ($key == '_id') {
248
                    continue;
249
                }
250
251
                if (!is_array($group)) {
252
                    $iiifData[$key] = $this->buildIiifDataGroup($key, $group);
253
                } else {
254
                    foreach ($group as $label => $value) {
255
                        if ($label == '_id') {
256
                            continue;
257
                        }
258
                        if (is_array($value)) {
259
                            $value = implode($this->settings['separator'], $value);
260
                        }
261
262
                        $iiifData[$key]['data'][] = $this->buildIiifDataGroup($label, $value);
263
                    }
264
                }
265
            }
266
        }
267
268
        return $iiifData;
269
    }
270
271
    /**
272
     * Builds the IIIF data array from label and value
273
     *
274
     * @access private
275
     *
276
     * @param string $label The label string
277
     * @param string $value The value string
278
     *
279
     * @return array The IIIF data array ready for output
280
     */
281
    private function buildIiifDataGroup(string $label, string $value): array
282
    {
283
        // NOTE: Labels are to be escaped in Fluid template
284
        if (IRI::isAbsoluteIri($value) && ($scheme = (new IRI($value))->getScheme()) == 'http' || $scheme == 'https') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $scheme does not seem to be defined for all execution paths leading up to this point.
Loading history...
introduced by
Consider adding parentheses for clarity. Current Interpretation: (Ubl\Iiif\Context\IRI::i...) || $scheme == 'https', Probably Intended Meaning: Ubl\Iiif\Context\IRI::is... || $scheme == 'https')
Loading history...
285
            //TODO: should really label be converted to empty string if equal to value?
286
            $label = $value == $label ? '' : $label;
287
            $buildUrl = true;
288
        } else {
289
            $buildUrl = false;
290
        }
291
292
        return [
293
            'label' => $label,
294
            'value' => $value,
295
            'buildUrl' => $buildUrl,
296
        ];
297
    }
298
299
    /**
300
     * Get metadata for given id array.
301
     *
302
     * @access private
303
     *
304
     * @return array metadata
305
     */
306
    private function getMetadata()
307
    {
308
        $metadata = [];
309
        if ($this->settings['rootline'] < 2) {
310
            // Get current structure's @ID.
311
            $ids = [];
312
            if (!empty($this->doc->physicalStructure[$this->requestData['page']]) && !empty($this->doc->smLinks['p2l'][$this->doc->physicalStructure[$this->requestData['page']]])) {
313
                foreach ($this->doc->smLinks['p2l'][$doc->physicalStructure[$this->requestData['page']]] as $logId) {
314
                    $count = $doc->getStructureDepth($logId);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $doc seems to be never defined.
Loading history...
315
                    $ids[$count][] = $logId;
316
                }
317
            }
318
            ksort($ids);
319
            reset($ids);
320
            // Check if we should display all metadata up to the root.
321
            if ($this->settings['rootline'] == 1) {
322
                foreach ($ids as $id) {
323
                    $metadata = $this->getMetadataForIds($id, $metadata);
324
                }
325
            } else {
326
                $id = array_pop($ids);
327
                if (is_array($id)) {
328
                    $metadata = $this->getMetadataForIds($id, $metadata);
329
                }
330
            }
331
        }
332
        return $metadata;
333
    }
334
335
    /**
336
     * Get metadata for given id array.
337
     *
338
     * @access private
339
     *
340
     * @param array $id: An array with ids
341
     * @param array $metadata: An array with metadata
342
     *
343
     * @return array metadata
344
     */
345
    private function getMetadataForIds($id, $metadata)
346
    {
347
        $useOriginalIiifManifestMetadata = $this->settings['originalIiifMetadata'] == 1 && $this->doc instanceof IiifManifest;
348
        foreach ($id as $sid) {
349
            if ($useOriginalIiifManifestMetadata) {
350
                $data = $this->doc->getManifestMetadata($sid, $this->settings['storagePid']);
351
            } else {
352
                $data = $this->doc->getMetadata($sid, $this->settings['storagePid']);
353
            }
354
            if (!empty($data)) {
355
                $data['_id'] = $sid;
356
                $metadata[] = $data;
357
            }
358
        }
359
        return $metadata;
360
    }
361
362
    /**
363
     * Sets default value for setting if not yet set.
364
     *
365
     * @access private
366
     *
367
     * @param string $setting name of setting
368
     * @param int $value 0 or 1
369
     *
370
     * @return void
371
     */
372
    private function setDefault($setting, $value) {
373
        if (!isset($this->settings[$setting])) {
374
            $this->settings[$setting] = $value;
375
        }
376
    }
377
}
378