Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions Classes/DataProcessor/GalleryDataProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

declare(strict_types=1);

/*
* This file is part of the package jweiland/jwtools2.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace JWeiland\Jwtools2\DataProcessor;

use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException;
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Resource\FileReference;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
use TYPO3\CMS\Frontend\ContentObject\Exception\ContentRenderingException;
use TYPO3\CMS\Frontend\DataProcessing\GalleryProcessor;

final readonly class GalleryDataProcessor implements DataProcessorInterface
{
public function __construct(
private GalleryProcessor $originalGalleryProcessor,
private ExtensionConfiguration $extensionConfiguration,
) {}

/**
* @throws ContentRenderingException
*/
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData,
): array {
$filesProcessedDataKey = (string)$cObj->stdWrapValue(
'filesProcessedDataKey',
$processorConfiguration,
'files',
);

if (isset($processedData[$filesProcessedDataKey]) && is_array($processedData[$filesProcessedDataKey])) {
/** @var FileReference[] $fileObjects */
$fileObjects = $processedData[$filesProcessedDataKey];
} else {
throw new ContentRenderingException(
'No files found for key ' . $filesProcessedDataKey . ' in $processedData.',
1779280032,
);
}

$requiredColumns = $this->getRequiredColumns();

if ($requiredColumns !== []) {
foreach ($fileObjects as $key => $fileObject) {
if (!$this->isValidFileObject($fileObject, $requiredColumns)) {
unset($fileObjects[$key]);
}
}

$processedData[$filesProcessedDataKey] = $fileObjects;
}

return $this->originalGalleryProcessor->process(
$cObj,
$contentObjectConfiguration,
$processorConfiguration,
$processedData,
);
}

private function isValidFileObject(FileReference $fileObject, array $requiredColumns): bool
{
// Only check image files here
if ($fileObject->getType() !== 2) {
return true;
}

foreach ($requiredColumns as $requiredColumn) {
if (!$fileObject->hasProperty($requiredColumn)) {
return false;
}

$value = $fileObject->getProperty($requiredColumn);
$trimmedValue = is_string($value) ? trim($value) : $value;

if ($trimmedValue === null || $trimmedValue === '') {
return false;
}
}

return true;
}

private function getRequiredColumns(): array
{
$requiredColumns = [];

try {
$requiredColumns = GeneralUtility::trimExplode(
',',
$this->extensionConfiguration->get('jwtools2', 'typo3RequiredColumnsForFiles'),
true,
);
} catch (ExtensionConfigurationExtensionNotConfiguredException|ExtensionConfigurationPathDoesNotExistException) {
}

return $requiredColumns;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

declare(strict_types=1);

/*
* This file is part of the package jweiland/jwtools2.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace JWeiland\Jwtools2\EventListener;

use TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceControlsEvent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException;
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Imaging\IconSize;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;

#[AsEventListener(
identifier: 'jwtools2/addMandatoryControlForFileReferences',
)]
final readonly class AddMandatoryControlForFileReferencesEventListener
{
public function __construct(
private IconFactory $iconFactory,
private ExtensionConfiguration $extensionConfiguration,
) {}

public function __invoke(ModifyFileReferenceControlsEvent $event): void
{
$record = $event->getRecord();
$requiredColumns = $this->getRequiredColumns();
if ($requiredColumns === []) {
return;
}

// Only check image files here
if ((int)($record['type'] ?? 0) !== 2) {
return;
}

foreach ($requiredColumns as $requiredColumn) {
$value = $record['uid_local'][0][$requiredColumn] ?? $record[$requiredColumn] ?? '';
$trimmedValue = is_string($value) ? trim($value) : $value;

if ($trimmedValue === null || $trimmedValue === '') {
$event->setControl(
'requiredColumns',
'<button type="button" class="btn btn-default" title="' . $this->getMandatoryMessage($requiredColumns) . '">
' . $this->iconFactory->getIcon('status-dialog-error', IconSize::SMALL)->render() . '
</button>',
);
return;
}
}
}

private function getRequiredColumns(): array
{
$requiredColumns = [];

try {
$requiredColumns = GeneralUtility::trimExplode(
',',
$this->extensionConfiguration->get('jwtools2', 'typo3RequiredColumnsForFiles'),
true,
);
} catch (ExtensionConfigurationExtensionNotConfiguredException|ExtensionConfigurationPathDoesNotExistException) {
}

return $requiredColumns;
}

protected function getMandatoryMessage(array $requiredColumns): string
{
return LocalizationUtility::translate(
'LLL:EXT:jwtools2/Resources/Private/Language/locallang_mod.xlf:warning.requiredColumns',
'Jwtools2',
[
implode(
', ',
$this->getTranslatedColumnNames(
$requiredColumns,
),
),
],
);
}

protected function getTranslatedColumnNames(array $requiredColumns): array
{
if (!$this->getLanguageService() instanceof LanguageService) {
return $requiredColumns;
}

foreach ($requiredColumns as $key => $requiredColumn) {
$label = BackendUtility::getItemLabel('sys_file', $requiredColumn);
if ($label === '' || $label === null) {
$label = BackendUtility::getItemLabel('sys_file_metadata', $requiredColumn);
}

if ($label === '' || $label === null) {
continue;
}

$translatedLabel = $this->getLanguageService()->sL($label);
if ($translatedLabel === '') {
continue;
}

$requiredColumns[$key] = $translatedLabel;
}

return $requiredColumns;
}

protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
Loading
Loading