Skip to content

Commit

Permalink
[FEATURE] Improve icon registry (#1038)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminkott authored Aug 13, 2021
1 parent 0398beb commit 0e55bdc
Show file tree
Hide file tree
Showing 39 changed files with 1,199 additions and 292 deletions.
10 changes: 5 additions & 5 deletions Build/phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ parameters:
count: 1
path: ../Classes/Utility/ExternalMediaUtility.php

-
message: "#^Variable property access on SimpleXMLElement\\.$#"
count: 2
path: ../Classes/Utility/SvgUtility.php

-
message: "#^Return type \\(mixed\\) of method BK2K\\\\BootstrapPackage\\\\ViewHelpers\\\\File\\\\IsAudioViewHelper\\:\\:renderStatic\\(\\) should be covariant with return type \\(string\\) of method TYPO3Fluid\\\\Fluid\\\\Core\\\\ViewHelper\\\\ViewHelperInterface\\:\\:renderStatic\\(\\)$#"
count: 1
Expand All @@ -20,11 +25,6 @@ parameters:
count: 1
path: ../Classes/ViewHelpers/File/IsMediaViewHelper.php

-
message: "#^Variable property access on SimpleXMLElement\\.$#"
count: 2
path: ../Classes/ViewHelpers/InlineSvgViewHelper.php

-
message: "#^Implicit array creation is not allowed \\- variable \\$EM_CONF might not exist\\.$#"
count: 1
Expand Down
91 changes: 91 additions & 0 deletions Classes/DataProcessing/IconsDataProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
declare(strict_types = 1);

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

namespace BK2K\BootstrapPackage\DataProcessing;

use BK2K\BootstrapPackage\Icons\FileIcon;
use BK2K\BootstrapPackage\Service\IconService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
use TYPO3\CMS\Frontend\DataProcessing\FilesProcessor;

/**
* Minimal TypoScript configuration
*
* 10 = BK2K\BootstrapPackage\DataProcessing\IconsDataProcessor
* 10 {
* iconSetFieldName = icon_set
* iconIdentifierFieldName = icon
* iconFileFieldName = icon_file
* as = icon
* }
*/
class IconsDataProcessor implements DataProcessorInterface
{
/**
* @var IconService
*/
protected $iconService;

/**
* Constructor
*/
public function __construct()
{
$this->iconService = GeneralUtility::makeInstance(IconService::class);
}

/**
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processorConfiguration The configuration of this processor
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
*/
public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
{
$icon = null;
$config = [
'iconSet' => (string) $cObj->stdWrapValue('iconSet', $processorConfiguration, ''),
'iconIdentifier' => (string) $cObj->stdWrapValue('iconIdentifier', $processorConfiguration, ''),
'iconFileFieldName' => (string) $cObj->stdWrapValue('iconFileFieldName', $processorConfiguration, ''),
];

if ($config['iconSet'] !== '' && $config['iconIdentifier'] !== '') {
$iconProvider = $this->iconService->getIconProviderForIdentifier($config['iconSet']);
if ($iconProvider !== null) {
$icon = $iconProvider->getIconList()->getIcon($config['iconIdentifier']);
}
} elseif ($config['iconFileFieldName'] !== '') {
$filesProcessor = GeneralUtility::makeInstance(FilesProcessor::class);
$filesData = $filesProcessor->process(
$cObj,
$contentObjectConfiguration,
['references.' => ['fieldName' => $config['iconFileFieldName']]],
['data' => $processedData['data']]
);
if (isset($filesData['files'][0])) {
$file = $filesData['files'][0];
$icon = (new FileIcon())
->setFile($file)
->setIdentifier($file->getIdentifier())
->setName($file->getName())
->setPreviewImage($file->getPublicUrl())
;
}
}

$targetVariableName = (string) $cObj->stdWrapValue('as', $processorConfiguration, 'icon');
$processedData[$targetVariableName] = $icon;

return $processedData;
}
}
140 changes: 140 additions & 0 deletions Classes/Icons/AbstractIcon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php
declare(strict_types = 1);

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

namespace BK2K\BootstrapPackage\Icons;

/**
* AbstractIcon
*/
abstract class AbstractIcon implements IconInterface
{
/**
* @var string
*/
protected $identifier;

/**
* @var string
*/
protected $name;

/**
* @var string
*/
protected $previewImage;

/**
* @var int
*/
protected $height = 16;

/**
* @var int
*/
protected $width = 16;

/**
* @param string $identifier
* @return self
*/
public function setIdentifier(string $identifier)
{
$this->identifier = $identifier;
return $this;
}

/**
* @return string
*/
public function getIdentifier(): string
{
return $this->identifier;
}

/**
* @param string $name
* @return self
*/
public function setName(string $name)
{
$this->name = $name;
return $this;
}

/**
* @return string
*/
public function getName(): string
{
return $this->name;
}

/**
* @param string $previewImage
* @return self
*/
public function setPreviewImage(string $previewImage)
{
$this->previewImage = $previewImage;
return $this;
}

/**
* @return string
*/
public function getPreviewImage(): string
{
return $this->previewImage;
}

/**
* @param int $height
* @return self
*/
public function setHeight(int $height)
{
$this->height = $height;
return $this;
}

/**
* @return int
*/
public function getHeight(): int
{
return $this->height;
}

/**
* @param int $width
* @return self
*/
public function setWidth(int $width)
{
$this->width = $width;
return $this;
}

/**
* @return int
*/
public function getWidth(): int
{
return $this->width;
}

/**
* @return string
*/
public function render(): string
{
return '';
}
}
84 changes: 84 additions & 0 deletions Classes/Icons/FileIcon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
declare(strict_types = 1);

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

namespace BK2K\BootstrapPackage\Icons;

use BK2K\BootstrapPackage\Utility\SvgUtility;
use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Service\ImageService;

/**
* FileIcon
*/
class FileIcon extends AbstractIcon
{
/**
* @var FileInterface
*/
protected $file;

/**
* @param FileInterface $file
* @return self
*/
public function setFile(FileInterface $file): self
{
$this->file = $file;
return $this;
}

/**
* @return FileInterface
*/
public function getFile(): FileInterface
{
return $this->file;
}

/**
* @return string
*/
public function render(): string
{
try {
$imageService = GeneralUtility::makeInstance(ImageService::class);
$image = $imageService->getImage('', $this->file, false);
$height = $this->getHeight();
$width = $this->getWidth();

if ($image->getExtension() === 'svg') {
return SvgUtility::getInlineSvg('', $image, $width, $height);
}

$processingInstructions = [
'width' => $width . 'c',
'height' => $height . 'c'
];
$processedImage = $imageService->applyProcessingInstructions($image, $processingInstructions);
$imageUri = $imageService->getImageUri($processedImage);

return '<img loading="lazy" src="' . $imageUri . '" height="' . $height . '" width="' . $width . '" />';
} catch (ResourceDoesNotExistException $e) {
// thrown if file does not exist
throw new \Exception($e->getMessage(), 1628773040, $e);
} catch (\UnexpectedValueException $e) {
// thrown if a file has been replaced with a folder
throw new \Exception($e->getMessage(), 1628773041, $e);
} catch (\RuntimeException $e) {
// RuntimeException thrown if a file is outside of a storage
throw new \Exception($e->getMessage(), 1628773042, $e);
} catch (\InvalidArgumentException $e) {
// thrown if file storage does not exist
throw new \Exception($e->getMessage(), 1628773043, $e);
}
}
}
Loading

0 comments on commit 0e55bdc

Please sign in to comment.