Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/composer/phpstan/phpstan-2.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-meyer authored Feb 1, 2025
2 parents 7c1cbdd + d5cabdb commit 17e7a79
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 33 deletions.
1 change: 1 addition & 0 deletions .github/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ parameters:
- '#Constant LOG_SEVERITY_ERROR not found\.#'
- '#Constant LOG_SEVERITY_NOTICE not found\.#'
- '#Constant LOG_SEVERITY_WARNING not found\.#'
- '#^Parameter \#2 \$callback of function array_filter expects \(callable\(mixed\)\: bool\)\|null, ''strlen'' given\.$#'
level: 5
paths:
- ../Classes/
Expand Down
2 changes: 1 addition & 1 deletion Build/Test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ services:
"
solr:
image: docker.io/solr:9
image: docker.io/solr:9.7
volumes:
- ${DLF_ROOT}/Configuration/ApacheSolr/configsets:/var/solr/data/configsets
- ./solr/modules/ocrsearch:/opt/solr/modules/ocrsearch
Expand Down
25 changes: 25 additions & 0 deletions Classes/Common/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
use TYPO3\CMS\Core\Resource\MimeTypeCollection;
use TYPO3\CMS\Core\Resource\MimeTypeDetector;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
Expand Down Expand Up @@ -988,4 +989,28 @@ function ($mimeType) use ($categories) {
}
return false;
}

/**
* Get file extensions for a given MIME type
*
* @param string $mimeType
* @return array
*/
public static function getFileExtensionsForMimeType(string $mimeType): array
{
$mimeTypeDetector = GeneralUtility::makeInstance(MimeTypeDetector::class);
return $mimeTypeDetector->getFileExtensionsForMimeType($mimeType);
}

/**
* Get MIME types for a given file extension
*
* @param string $fileExtension
* @return array
*/
public static function getMimeTypesForFileExtension(string $fileExtension): array
{
$mimeTypeDetector = GeneralUtility::makeInstance(MimeTypeDetector::class);
return $mimeTypeDetector->getMimeTypesForFileExtension($fileExtension);
}
}
9 changes: 4 additions & 5 deletions Classes/Controller/ListViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,13 @@ public function injectMetadataRepository(MetadataRepository $metadataRepository)
public function mainAction(): ResponseInterface
{
$this->searchParams = $this->getParametersSafely('searchParameter');
$this->searchParams = is_array($this->searchParams) ? array_filter($this->searchParams, 'strlen') : [];

// extract collection(s) from collection parameter
$collections = [];
if (is_array($this->searchParams) && array_key_exists('collection', $this->searchParams)) {
if (array_key_exists('collection', $this->searchParams)) {
foreach(explode(',', $this->searchParams['collection']) as $collectionEntry) {
if (!empty($collectionEntry)) {
$collections[] = $this->collectionRepository->findByUid((int) $collectionEntry);
}
$collections[] = $this->collectionRepository->findByUid((int) $collectionEntry);
}
}

Expand All @@ -104,7 +103,7 @@ public function mainAction(): ResponseInterface

$solrResults = null;
$numResults = 0;
if (is_array($this->searchParams) && !empty($this->searchParams)) {
if (!empty($this->searchParams)) {
$solrResults = $this->documentRepository->findSolrByCollections($collections, $this->settings, $this->searchParams, $listedMetadata, $indexedMetadata);
$numResults = $solrResults->getNumFound();

Expand Down
8 changes: 8 additions & 0 deletions Classes/Controller/NavigationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ public function mainAction(): ResponseInterface
$this->viewData['requestData'] = $this->requestData;
}

// get the closest previous sibling or leaf node
$prevDocumentUid = $this->documentRepository->getPreviousDocumentUid($this->document->getUid());
$this->view->assign('documentBack', $prevDocumentUid);

// get the closest next sibling or leaf node
$nextDocumentUid = $this->documentRepository->getNextDocumentUid($this->document->getUid());
$this->view->assign('documentForward', $nextDocumentUid);

// Steps for X pages backward / forward. Double page view uses double steps.
$pageSteps = $this->settings['pageStep'] * ($this->requestData['double'] + 1);

Expand Down
2 changes: 1 addition & 1 deletion Classes/Controller/PageViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ protected function getMeasures(int $page, MetsDocument $specificDoc = null, $doc
$measureCoordsFromCurrentSite = [];
$measureCounterToMeasureId = [];
$measureLinks = [];
$defaultFileId = $doc->physicalStructureInfo[$currentPhysId]['files']['DEFAULT'];
$defaultFileId = $doc->physicalStructureInfo[$currentPhysId]['files']['DEFAULT'] ?? null;
if ($doc instanceof MetsDocument) {
if (isset($defaultFileId)) {
$musicalStruct = $doc->musicalStructureInfo;
Expand Down
17 changes: 10 additions & 7 deletions Classes/Controller/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public function mainAction(): ResponseInterface

// if search was triggered, get search parameters from POST variables
$this->searchParams = $this->getParametersSafely('searchParameter');

// if search was triggered by the ListView plugin, get the parameters from GET variables
// replace with $this->request->getQueryParams() when dropping support for Typo3 v11, see Deprecation-100596
$listRequestData = GeneralUtility::_GPmerged('tx_dlf_listview');
Expand All @@ -130,13 +131,15 @@ public function mainAction(): ResponseInterface
$GLOBALS['TSFE']->fe_user->setKey('ses', 'search', $this->searchParams);
}

$this->searchParams = is_array($this->searchParams) ? array_filter($this->searchParams, 'strlen') : [];

// sanitize date search input
if (!empty($this->searchParams['dateFrom']) || !empty($this->searchParams['dateTo'])) {
if (empty($this->searchParams['dateFrom']) && !empty($this->searchParams['dateTo'])) {
if (array_key_exists('dateFrom', $this->searchParams) || array_key_exists('dateTo', $this->searchParams)) {
if (!array_key_exists('dateFrom', $this->searchParams) && array_key_exists('dateTo', $this->searchParams)) {
$this->searchParams['dateFrom'] = '*';
}

if (empty($this->searchParams['dateTo']) && !empty($this->searchParams['dateFrom'])) {
if (!array_key_exists('dateTo', $this->searchParams) && array_key_exists('dateFrom', $this->searchParams)) {
$this->searchParams['dateTo'] = 'NOW';
}

Expand Down Expand Up @@ -168,7 +171,7 @@ public function mainAction(): ResponseInterface

// If no search has been executed, no variables have to be prepared.
// An empty form will be shown.
if (is_array($this->searchParams) && !empty($this->searchParams)) {
if (!empty($this->searchParams)) {
// get all sortable metadata records
$sortableMetadata = $this->metadataRepository->findByIsSortable(true);

Expand Down Expand Up @@ -276,7 +279,7 @@ public function makeFacetsMenuArray(array $facets): array
// Set search query.
$searchParams = $this->searchParams;
if (
(!empty($searchParams['fulltext']))
(array_key_exists('fulltext', $searchParams))
|| preg_match('/' . $fields['fulltext'] . ':\((.*)\)/', trim($searchParams['query']), $matches)
) {
// If the query already is a fulltext query e.g using the facets
Expand All @@ -298,7 +301,7 @@ public function makeFacetsMenuArray(array $facets): array
}

// add filter query for date search
if (!empty($this->searchParams['dateFrom']) && !empty($this->searchParams['dateTo'])) {
if (array_key_exists('dateFrom', $this->searchParams) && array_key_exists('dateTo', $this->searchParams)) {
// combine dateFrom and dateTo into filterquery as range search
$search['params']['filterquery'][]['query'] = '{!join from=' . $fields['uid'] . ' to=' . $fields['uid'] . '}' . $fields['date'] . ':[' . $this->searchParams['dateFrom'] . ' TO ' . $this->searchParams['dateTo'] . ']';
}
Expand Down Expand Up @@ -326,7 +329,7 @@ public function makeFacetsMenuArray(array $facets): array
}
}

if (isset($this->searchParams['fq']) && is_array($this->searchParams['fq'])) {
if (array_key_exists('fq', $this->searchParams) && is_array($this->searchParams['fq'])) {
foreach ($this->searchParams['fq'] as $fq) {
$search['params']['filterquery'][]['query'] = $fq;
}
Expand Down
30 changes: 14 additions & 16 deletions Classes/Controller/ToolboxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,13 @@ private function renderToolByName(string $tool): void
*
* @return array Array of image information's.
*/
public function getImage(int $page): array
private function getImage(int $page): array
{
// Get @USE value of METS fileGroup.
$image = $this->getFile($page, GeneralUtility::trimExplode(',', $this->settings['fileGrpsImageDownload']));
switch ($image['mimetype']) {
case 'image/jpeg':
$image['mimetypeLabel'] = ' (JPG)';
break;
case 'image/tiff':
$image['mimetypeLabel'] = ' (TIFF)';
break;
default:
$image['mimetypeLabel'] = '';
if (isset($image['mimetype'])) {
$fileExtension = Helper::getFileExtensionsForMimeType($image['mimetype']);
$image['mimetypeLabel'] = !empty($fileExtension) ? ' (' . strtoupper($fileExtension[0]) . ')' : '';
}
return $image;
}
Expand Down Expand Up @@ -321,14 +315,18 @@ private function renderImageDownloadTool(): void
private function getFile(int $page, array $fileGrps): array
{
$file = [];
$physicalStructureInfo = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$page]] ?? null;
while ($fileGrp = @array_pop($fileGrps)) {
$physicalStructureInfo = $this->currentDocument->physicalStructureInfo[$this->currentDocument->physicalStructure[$page]];
$fileId = $physicalStructureInfo['files'][$fileGrp];
if (!empty($fileId)) {
$file['url'] = $this->currentDocument->getDownloadLocation($fileId);
$file['mimetype'] = $this->currentDocument->getFileMimeType($fileId);
if (isset($physicalStructureInfo['files'][$fileGrp])) {
$fileId = $physicalStructureInfo['files'][$fileGrp];
if (!empty($fileId)) {
$file['url'] = $this->currentDocument->getDownloadLocation($fileId);
$file['mimetype'] = $this->currentDocument->getFileMimeType($fileId);
} else {
$this->logger->warning('File not found in fileGrp "' . $fileGrp . '"');
}
} else {
$this->logger->warning('File not found in fileGrp "' . $fileGrp . '"');
$this->logger->warning('fileGrp "' . $fileGrp . '" not found in Document mets:fileSec');
}
}
return $file;
Expand Down
168 changes: 168 additions & 0 deletions Classes/Domain/Repository/DocumentRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -645,4 +645,172 @@ private function findSolr($collections, $settings, $searchParams, $listedMetadat
$search->prepare();
return $search;
}

/**
* Find the uid of the previous document relative to the current document uid.
* Otherwise backtrack the closest previous leaf node.
*
* @access public
*
* @param int $uid
*
* @return int|null
*/
public function getPreviousDocumentUid($uid)
{
$currentDocument = $this->findOneByUid($uid);
if ($currentDocument) {
$currentVolume = '';
$parentId = $currentDocument->getPartof();

if ($parentId) {

$currentVolume = (string) $currentDocument->getVolumeSorting();

$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents');

// Grab previous volume
$prevDocument = $queryBuilder
->select(
'tx_dlf_documents.uid AS uid'
)
->from('tx_dlf_documents')
->where(
$queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $parentId),
'tx_dlf_documents.volume_sorting < \'' . $currentVolume . '\''
)
->add('orderBy', 'volume_sorting desc')
->addOrderBy('tx_dlf_documents.volume_sorting')
->execute()
->fetch();

if (!empty($prevDocument)) {
return $prevDocument['uid'];
}

return $this->getLastChild($this->getPreviousDocumentUid($parentId));
}
}

return null;
}

/**
* Find the uid of the next document relative to the current document uid.
* Otherwise backtrack the closest next leaf node.
*
* @access public
*
* @param int $uid
*
* @return int|null
*/
public function getNextDocumentUid($uid)
{
$currentDocument = $this->findOneByUid($uid);
if ($currentDocument) {
$currentVolume = '';
$parentId = $currentDocument->getPartof();

if ($parentId) {

$currentVolume = (string) $currentDocument->getVolumeSorting();

$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents');

// Grab next volume
$nextDocument = $queryBuilder
->select(
'tx_dlf_documents.uid AS uid'
)
->from('tx_dlf_documents')
->where(
$queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $parentId),
'tx_dlf_documents.volume_sorting > \'' . $currentVolume . '\''
)
->add('orderBy', 'volume_sorting asc')
->addOrderBy('tx_dlf_documents.volume_sorting')
->execute()
->fetch();

if (!empty($nextDocument)) {
return $nextDocument['uid'];
}

return $this->getFirstChild($this->getNextDocumentUid($parentId));
}
}

return null;
}

/**
* Find the uid of the first leaf node
*
* @access public
*
* @param int $uid
*
* @return int
*/
public function getFirstChild($uid)
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents');

$child = $queryBuilder
->select(
'tx_dlf_documents.uid AS uid'
)
->from('tx_dlf_documents')
->where(
$queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $uid)
)
->add('orderBy', 'volume_sorting asc')
->addOrderBy('tx_dlf_documents.volume_sorting')
->execute()
->fetch();

if (empty($child['uid'])) {
return $uid;
}

return $this->getFirstChild($child['uid']);
}

/**
* Find the uid of the last leaf node
*
* @access public
*
* @param int $uid
*
* @return int
*/
public function getLastChild($uid)
{
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('tx_dlf_documents');

$child = $queryBuilder
->select(
'tx_dlf_documents.uid AS uid'
)
->from('tx_dlf_documents')
->where(
$queryBuilder->expr()->eq('tx_dlf_documents.partof', (int) $uid)
)
->add('orderBy', 'volume_sorting desc')
->addOrderBy('tx_dlf_documents.volume_sorting')
->execute()
->fetch();

if (empty($child['uid'])) {
return $uid;
}

return $this->getFirstChild($child['uid']);
}
}
Loading

0 comments on commit 17e7a79

Please sign in to comment.