Skip to content

Commit 1374b17

Browse files
Merge branch 'master' into ext-tables
2 parents 88e7024 + 8d37dc1 commit 1374b17

37 files changed

+900
-576
lines changed

.github/ISSUE_TEMPLATE/task-for-the-development-fund.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: Task for the development fund
33
about: A working package which may be sponsored by the Kitodo e.V. development fund.
44
title: "[FUND] "
5-
labels: ⭐ development fund 2024
5+
labels: ⭐ development fund 2025
66
assignees: ''
77

88
---

.github/codeql.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
name: "CodeQL Configuration"
1+
name: CodeQL Configuration
22

3-
queries:
4-
- uses: security-and-quality
3+
queries:
4+
- uses: security-and-quality
55

6-
query-filters:
7-
- exclude:
8-
problem.severity:
9-
- note
6+
query-filters:
7+
- exclude:
8+
problem.severity:
9+
- note
1010

11-
paths-ignore:
12-
- Resources/Public/JavaScript/jPlayer
13-
- Resources/Public/JavaScript/jQuery
14-
- Resources/Public/JavaScript/jQueryUI
15-
- Resources/Public/JavaScript/OpenLayers
16-
- Resources/Public/JavaScript/Toastify
11+
paths-ignore:
12+
- Resources/Public/JavaScript/jPlayer
13+
- Resources/Public/JavaScript/jQuery
14+
- Resources/Public/JavaScript/jQueryUI
15+
- Resources/Public/JavaScript/OpenLayers
16+
- Resources/Public/JavaScript/Toastify

.github/phpstan.neon

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
parameters:
2-
ignoreErrors:
3-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::countByPid\(\)\.#'
4-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findByIsListed\(\)\.#'
5-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findByIsSortable\(\)\.#'
6-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByFeUserId\(\)\.#'
7-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByIndexName\(\)\.#'
8-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByLocation\(\)\.#'
9-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByPid\(\)\.#'
10-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByRecordId\(\)\.#'
11-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneBySessionId\(\)\.#'
12-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByType\(\)\.#'
13-
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByUid\(\)\.#'
14-
- '#Call to an undefined method Psr\\Http\\Message\\RequestFactoryInterface::request\(\)\.#'
15-
- '#Call to an undefined method Solarium\\Core\\Query\\DocumentInterface::setField\(\)\.#'
16-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getHeight\(\)\.#'
17-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getWidth\(\)\.#'
18-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getPossibleTextAnnotationContainers\(\)\.#'
19-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getTextAnnotations\(\)\.#'
20-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\ManifestInterface::getOriginalJsonArray\(\)\.#'
21-
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\RangeInterface::getMemberRangesAndRanges\(\)\.#'
22-
- '#Constant LOG_SEVERITY_ERROR not found\.#'
23-
- '#Constant LOG_SEVERITY_NOTICE not found\.#'
24-
- '#Constant LOG_SEVERITY_WARNING not found\.#'
25-
- '#Constant TYPO3_MODE not found\.#'
26-
level: 5
27-
paths:
28-
- ../Classes/
29-
excludePaths:
30-
- ../Classes/Controller/OaiPmhController.php
31-
treatPhpDocTypesAsCertain: false
2+
ignoreErrors:
3+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::countByPid\(\)\.#'
4+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findByIsListed\(\)\.#'
5+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findByIsSortable\(\)\.#'
6+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByFeUserId\(\)\.#'
7+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByIndexName\(\)\.#'
8+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByLocation\(\)\.#'
9+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByPid\(\)\.#'
10+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByRecordId\(\)\.#'
11+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneBySessionId\(\)\.#'
12+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByType\(\)\.#'
13+
- '#Call to an undefined method Kitodo\\Dlf\\Domain\\Repository\\[a-zA-Z]+Repository::findOneByUid\(\)\.#'
14+
- '#Call to an undefined method Psr\\Http\\Message\\RequestFactoryInterface::request\(\)\.#'
15+
- '#Call to an undefined method Solarium\\Core\\Query\\DocumentInterface::setField\(\)\.#'
16+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getHeight\(\)\.#'
17+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getWidth\(\)\.#'
18+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getPossibleTextAnnotationContainers\(\)\.#'
19+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\IiifResourceInterface::getTextAnnotations\(\)\.#'
20+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\ManifestInterface::getOriginalJsonArray\(\)\.#'
21+
- '#Call to an undefined method Ubl\\Iiif\\Presentation\\Common\\Model\\Resources\\RangeInterface::getMemberRangesAndRanges\(\)\.#'
22+
- '#Constant LOG_SEVERITY_ERROR not found\.#'
23+
- '#Constant LOG_SEVERITY_NOTICE not found\.#'
24+
- '#Constant LOG_SEVERITY_WARNING not found\.#'
25+
- '#Constant TYPO3_MODE not found\.#'
26+
level: 5
27+
paths:
28+
- ../Classes/
29+
excludePaths:
30+
- ../Classes/Controller/OaiPmhController.php
31+
treatPhpDocTypesAsCertain: false

.github/pull.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ rules:
1818
- base: 4.x
1919
upstream: kitodo:4.x
2020
mergeMethod: hardreset
21+
- base: 5.x
22+
upstream: kitodo:5.x
23+
mergeMethod: hardreset

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
name: "CodeQL"
1+
name: CodeQL
22

33
on:
44
push:
5-
branches: [ "master", "1.x", "2.x", "3.2.x", "3.3.x", "4.x" ]
5+
branches: [ "master", "1.x", "2.x", "3.2.x", "3.3.x", "4.x", "5.x" ]
66
pull_request:
77
branches: [ "master" ]
88

99
jobs:
1010
analyze:
11-
name: Analyze
11+
name: Static Code Analysis
1212
runs-on: ubuntu-latest
1313
permissions:
1414
actions: read

.github/workflows/documentation.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
name: Build Documentation
1+
name: Documentation
22

33
on: [ push, pull_request ]
44

55
jobs:
66
tests:
7-
name: Documentation
7+
name: Build Test
88
runs-on: ubuntu-latest
99
steps:
1010
- name: Checkout

.github/workflows/phpstan.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88

99
jobs:
1010
phpstan:
11+
name: Static Code Analysis
1112
runs-on: ubuntu-latest
1213
steps:
1314
- name: Checkout code

.github/workflows/tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88

99
jobs:
1010
test:
11+
name: TYPO3
1112
runs-on: ubuntu-latest
1213
strategy:
1314
matrix:

Classes/Command/BaseCommand.php

Lines changed: 73 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Kitodo\Dlf\Domain\Model\Collection;
2323
use Kitodo\Dlf\Domain\Model\Document;
2424
use Kitodo\Dlf\Domain\Model\Library;
25+
use Kitodo\Dlf\Validation\DocumentValidator;
2526
use Symfony\Component\Console\Command\Command;
2627
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
2728
use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -123,25 +124,16 @@ public function __construct(
123124
*
124125
* @param int $storagePid The storage pid
125126
*
126-
* @return bool
127+
* @return void
127128
*/
128-
protected function initializeRepositories(int $storagePid): bool
129+
protected function initializeRepositories(int $storagePid): void
129130
{
130-
if (MathUtility::canBeInterpretedAsInteger($storagePid)) {
131-
$frameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
132-
133-
$frameworkConfiguration['persistence']['storagePid'] = MathUtility::forceIntegerInRange((int) $storagePid, 0);
134-
$this->configurationManager->setConfiguration($frameworkConfiguration);
135-
136-
// Get extension configuration.
137-
$this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf');
138-
} else {
139-
return false;
140-
}
141-
$this->storagePid = MathUtility::forceIntegerInRange((int) $storagePid, 0);
131+
$frameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
132+
$frameworkConfiguration['persistence']['storagePid'] = MathUtility::forceIntegerInRange($storagePid, 0);
133+
$this->configurationManager->setConfiguration($frameworkConfiguration);
134+
$this->extConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('dlf');
135+
$this->storagePid = MathUtility::forceIntegerInRange($storagePid, 0);
142136
$this->persistenceManager = GeneralUtility::makeInstance(PersistenceManager::class);
143-
144-
return true;
145137
}
146138

147139
/**
@@ -216,71 +208,70 @@ protected function saveToDatabase(Document $document): bool
216208
$doc->cPid = $this->storagePid;
217209

218210
$metadata = $doc->getToplevelMetadata($this->storagePid);
211+
$validator = new DocumentValidator($metadata, explode(',', $this->extConf['general']['requiredMetadataFields']));
212+
213+
if ($validator->hasAllMandatoryMetadataFields()) {
214+
// set title data
215+
$document->setTitle($metadata['title'][0] ? : '');
216+
$document->setTitleSorting($metadata['title_sorting'][0] ? : '');
217+
$document->setPlace(implode('; ', $metadata['place']));
218+
$document->setYear(implode('; ', $metadata['year']));
219+
$document->setAuthor($this->getAuthors($metadata['author']));
220+
$document->setThumbnail($doc->thumbnail ? : '');
221+
$document->setMetsLabel($metadata['mets_label'][0] ? : '');
222+
$document->setMetsOrderlabel($metadata['mets_orderlabel'][0] ? : '');
223+
224+
$structure = $this->structureRepository->findOneByIndexName($metadata['type'][0]);
225+
$document->setStructure($structure);
226+
227+
if (is_array($metadata['collection'])) {
228+
$this->addCollections($document, $metadata['collection']);
229+
}
219230

220-
// set title data
221-
$document->setTitle($metadata['title'][0] ? : '');
222-
$document->setTitleSorting($metadata['title_sorting'][0] ? : '');
223-
$document->setPlace(implode('; ', $metadata['place']));
224-
$document->setYear(implode('; ', $metadata['year']));
225-
226-
// Remove appended "valueURI" from authors' names for storing in database.
227-
foreach ($metadata['author'] as $i => $author) {
228-
$splitName = explode(pack('C', 31), $author);
229-
$metadata['author'][$i] = $splitName[0];
230-
}
231-
$document->setAuthor($this->getAuthors($metadata['author']));
232-
$document->setThumbnail($doc->thumbnail ? : '');
233-
$document->setMetsLabel($metadata['mets_label'][0] ? : '');
234-
$document->setMetsOrderlabel($metadata['mets_orderlabel'][0] ? : '');
235-
236-
$structure = $this->structureRepository->findOneByIndexName($metadata['type'][0]);
237-
$document->setStructure($structure);
231+
// set identifiers
232+
$document->setProdId($metadata['prod_id'][0] ? : '');
233+
$document->setOpacId($metadata['opac_id'][0] ? : '');
234+
$document->setUnionId($metadata['union_id'][0] ? : '');
235+
236+
$document->setRecordId($metadata['record_id'][0]);
237+
$document->setUrn($metadata['urn'][0] ? : '');
238+
$document->setPurl($metadata['purl'][0] ? : '');
239+
$document->setDocumentFormat($metadata['document_format'][0] ? : '');
240+
241+
// set access
242+
$document->setLicense($metadata['license'][0] ? : '');
243+
$document->setTerms($metadata['terms'][0] ? : '');
244+
$document->setRestrictions($metadata['restrictions'][0] ? : '');
245+
$document->setOutOfPrint($metadata['out_of_print'][0] ? : '');
246+
$document->setRightsInfo($metadata['rights_info'][0] ? : '');
247+
$document->setStatus(0);
248+
249+
$this->setOwner($metadata['owner'][0]);
250+
$document->setOwner($this->owner);
251+
252+
// set volume data
253+
$document->setVolume($metadata['volume'][0] ? : '');
254+
$document->setVolumeSorting($metadata['volume_sorting'][0] ? : $metadata['mets_order'][0] ? : '');
255+
256+
// Get UID of parent document.
257+
if ($document->getDocumentFormat() === 'METS') {
258+
$document->setPartof($this->getParentDocumentUidForSaving($document));
259+
}
238260

239-
if (is_array($metadata['collection'])) {
240-
$this->addCollections($document, $metadata['collection']);
241-
}
261+
if ($document->getUid() === null) {
262+
// new document
263+
$this->documentRepository->add($document);
264+
} else {
265+
// update of existing document
266+
$this->documentRepository->update($document);
267+
}
242268

243-
// set identifiers
244-
$document->setProdId($metadata['prod_id'][0] ? : '');
245-
$document->setOpacId($metadata['opac_id'][0] ? : '');
246-
$document->setUnionId($metadata['union_id'][0] ? : '');
247-
248-
$document->setRecordId($metadata['record_id'][0] ? : ''); // (?) $doc->recordId
249-
$document->setUrn($metadata['urn'][0] ? : '');
250-
$document->setPurl($metadata['purl'][0] ? : '');
251-
$document->setDocumentFormat($metadata['document_format'][0] ? : '');
252-
253-
// set access
254-
$document->setLicense($metadata['license'][0] ? : '');
255-
$document->setTerms($metadata['terms'][0] ? : '');
256-
$document->setRestrictions($metadata['restrictions'][0] ? : '');
257-
$document->setOutOfPrint($metadata['out_of_print'][0] ? : '');
258-
$document->setRightsInfo($metadata['rights_info'][0] ? : '');
259-
$document->setStatus(0);
260-
261-
$this->setOwner($metadata['owner'][0]);
262-
$document->setOwner($this->owner);
263-
264-
// set volume data
265-
$document->setVolume($metadata['volume'][0] ? : '');
266-
$document->setVolumeSorting($metadata['volume_sorting'][0] ? : $metadata['mets_order'][0] ? : '');
267-
268-
// Get UID of parent document.
269-
if ($document->getDocumentFormat() === 'METS') {
270-
$document->setPartof($this->getParentDocumentUidForSaving($document));
271-
}
269+
$this->persistenceManager->persistAll();
272270

273-
if ($document->getUid() === null) {
274-
// new document
275-
$this->documentRepository->add($document);
276-
} else {
277-
// update of existing document
278-
$this->documentRepository->update($document);
271+
return true;
279272
}
280273

281-
$this->persistenceManager->persistAll();
282-
283-
return true;
274+
return false;
284275
}
285276

286277
/**
@@ -346,7 +337,7 @@ private function addCollections(Document &$document, array $collections): void
346337
$documentCollection = GeneralUtility::makeInstance(Collection::class);
347338
$documentCollection->setIndexName($collection);
348339
$documentCollection->setLabel($collection);
349-
$documentCollection->setOaiName((!empty($this->extConf['publishNewCollections']) ? Helper::getCleanString($collection) : ''));
340+
$documentCollection->setOaiName((!empty($this->extConf['general']['publishNewCollections']) ? Helper::getCleanString($collection) : ''));
350341
$documentCollection->setIndexSearch('');
351342
$documentCollection->setDescription('');
352343
// add to CollectionRepository
@@ -371,6 +362,12 @@ private function addCollections(Document &$document, array $collections): void
371362
*/
372363
private function getAuthors(array $metadataAuthor): string
373364
{
365+
// Remove appended "valueURI" from authors' names for storing in database.
366+
foreach ($metadataAuthor as $i => $author) {
367+
$splitName = explode(pack('C', 31), $author);
368+
$metadataAuthor[$i] = $splitName[0];
369+
}
370+
374371
$authors = '';
375372
$delimiter = '; ';
376373
$ellipsis = 'et al.';

Classes/Command/DeleteCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8181
$io = new SymfonyStyle($input, $output);
8282
$io->title($this->getDescription());
8383

84-
$this->initializeRepositories($input->getOption('pid'));
84+
$this->initializeRepositories((int) $input->getOption('pid'));
8585

8686
if ($this->storagePid == 0) {
8787
$io->error('ERROR: No valid PID (' . $this->storagePid . ') given.');

0 commit comments

Comments
 (0)