Skip to content

Commit

Permalink
feat: add inline svg view helper
Browse files Browse the repository at this point in the history
  • Loading branch information
tgaertner committed Aug 14, 2024
1 parent d189b92 commit 90f0ac0
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 0 deletions.
77 changes: 77 additions & 0 deletions Classes/Utility/SvgUtility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace Xima\XimaTypo3Toolbox\Utility;

class SvgUtility
{
/**
* @param string $svgContent
* @param array $tags
* @return string
* @throws \DOMException
*/
public function getInlineSvg(
string $svgContent,
array $tags = []
): string {
$svgElement = simplexml_load_string($svgContent);
if (!$svgElement instanceof \SimpleXMLElement) {
return '';
}

$domXml = dom_import_simplexml($svgElement);
$ownerDocument = $domXml->ownerDocument;
if (!$ownerDocument instanceof \DOMDocument) {
return '';
}

if ($tags['title']) {
$titleElement = $ownerDocument->createElement('title', htmlspecialchars((string)$tags['title']));
if (!$titleElement instanceof \DOMElement) {
return '';
}
$domXml->prepend($titleElement);
}

$tags['id'] = htmlspecialchars(trim((string)$tags['id']));
if ($tags['id'] !== '') {
$domXml->setAttribute('id', $tags['id']);
}

$tags['class'] = htmlspecialchars(trim((string)$tags['class']));
if ($tags['class'] !== '') {
$domXml->setAttribute('class', $tags['class']);
}

if ((int)$tags['height'] > 0) {
$domXml->setAttribute('height', (string)$tags['height']);
}

if ((int)$tags['width'] > 0) {
$domXml->setAttribute('width', (string)$tags['width']);
}

if ($tags['ariaHidden']) {
$domXml->setAttribute('aria-hidden', $tags['ariaHidden']);
}

$tags['viewBox'] = htmlspecialchars(trim((string)$tags['viewBox']));
if ($tags['viewBox'] !== '') {
$domXml->setAttribute('viewBox', $tags['viewBox']);
}

if (is_array($tags['data'])) {
foreach ($tags['data'] as $dataAttributeKey => $dataAttributeValue) {
$dataAttributeKey = htmlspecialchars(trim((string)$dataAttributeKey));
$dataAttributeValue = htmlspecialchars(trim((string)$dataAttributeValue));
if ($dataAttributeKey !== '' && $dataAttributeValue !== '') {
$domXml->setAttribute('data-' . $dataAttributeKey, $dataAttributeValue);
}
}
}

return (string)$ownerDocument->saveXML($ownerDocument->documentElement);
}
}
86 changes: 86 additions & 0 deletions Classes/ViewHelpers/InlineSvgViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

namespace Xima\XimaTypo3Toolbox\ViewHelpers;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
use Xima\XimaTypo3Toolbox\Utility\SvgUtility;

/*
* Usage example:
*
* <html xmlns:xt3="http://typo3.org/ns/Xima/XimaTypo3Toolbox/ViewHelpers" [...]
*
* <xt3:inlineSvg
src="{svg.originalFile.storage.storageRecord.name}{svg.originalFile.identifier}"
aria-hidden="true"
class="myclass"
width="600"
height="300"
/>
*/
class InlineSvgViewHelper extends AbstractViewHelper
{
/**
* Initialize arguments.
*
* @throws Exception
*/
public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument('src', 'string', 'A path to a file', true);
$this->registerArgument('id', 'string', 'Id to set in the svg');
$this->registerArgument('class', 'string', 'Css class(es) for the svg');
$this->registerArgument('width', 'string', 'Width of the svg.');
$this->registerArgument('height', 'string', 'Height of the svg.');
$this->registerArgument('viewBox', 'string', 'Specifies the view box for the svg');
$this->registerArgument('aria-hidden', 'string', 'Sets the visibility of the svg for screen readers');
$this->registerArgument('title', 'string', 'Title of the svg');
$this->registerArgument('data', 'array', 'Array of data-attributes');
}

/**
* @return string
* @throws \Exception
*/
public function render(): string
{
if ((string)$this->arguments['src'] === '') {
throw new \Exception('You must specify a string src.', 1630054037);
}

$fullPath = GeneralUtility::getFileAbsFileName((string)$this->arguments['src']);

if (!file_exists($fullPath)) {
return '';
}

if (pathinfo($fullPath, PATHINFO_EXTENSION) !== 'svg') {
throw new \Exception('You must provide a svg file.', 1630401474);
}

$svgContent = file_get_contents($fullPath);
if (!$svgContent) {
throw new \Exception('The svg file must not be empty.', 1630401503);
}

$attributes = [
'id' => $this->arguments['id'],
'class' => $this->arguments['class'],
'width' => $this->arguments['width'],
'height' => $this->arguments['height'],
'viewBox' => $this->arguments['viewBox'],
'ariaHidden' => $this->arguments['aria-hidden'],
'title' => $this->arguments['title'],
'data' => $this->arguments['data'],
];

/** @var SvgUtility $svgUtility */
$svgUtility = GeneralUtility::makeInstance(SvgUtility::class);
return $svgUtility->getInlineSvg($svgContent, $attributes);
}
}

0 comments on commit 90f0ac0

Please sign in to comment.