TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* This is the base class for ViewHelpers that work with encodings.
|
||||
* Currently, that are format.htmlentities and format.htmlentitiesDecode
|
||||
*/
|
||||
abstract class AbstractEncodingViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $defaultEncoding;
|
||||
|
||||
/**
|
||||
* Resolve the default encoding. If none is set in Frontend or Backend, uses UTF-8.
|
||||
*/
|
||||
protected static function resolveDefaultEncoding(): string
|
||||
{
|
||||
if (self::$defaultEncoding === null) {
|
||||
self::$defaultEncoding = 'UTF-8';
|
||||
}
|
||||
return self::$defaultEncoding;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper which formats an integer (byte count) into specific human-readable output.
|
||||
*
|
||||
* ```
|
||||
* <f:format.bytes decimals="2" decimalSeparator="." thousandsSeparator=",">{file.size}</f:format.bytes>
|
||||
* <f:format.bytes decimals="2" decimalSeparator="." thousandsSeparator="," units="KB,MB,GB" value="{file.size}" />
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-bytes
|
||||
*/
|
||||
final class BytesViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Output is escaped already. We must not escape children, to avoid double encoding.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('value', 'int|float|string', 'The incoming data to convert, or NULL if VH children should be used');
|
||||
$this->registerArgument('decimals', 'int', 'The number of digits after the decimal point', false, 0);
|
||||
$this->registerArgument('decimalSeparator', 'string', 'The decimal point character', false, '.');
|
||||
$this->registerArgument('thousandsSeparator', 'string', 'The character for grouping the thousand digits', false, ',');
|
||||
$this->registerArgument('units', 'string', 'comma separated list of available units, default is LocalizationUtility::translate(\'viewhelper.format.bytes.units\', \'fluid\')');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the supplied byte count as a human-readable string.
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
if ($this->arguments['units'] !== null) {
|
||||
$units = $this->arguments['units'];
|
||||
} else {
|
||||
$units = LocalizationUtility::translate('viewhelper.format.bytes.units', 'fluid');
|
||||
}
|
||||
$units = GeneralUtility::trimExplode(',', (string)$units, true);
|
||||
$value = $this->renderChildren();
|
||||
if (is_numeric($value)) {
|
||||
$value = (float)$value;
|
||||
} else {
|
||||
$value = 0;
|
||||
}
|
||||
$bytes = max($value, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
$bytes /= 2 ** (10 * $pow);
|
||||
return sprintf(
|
||||
'%s %s',
|
||||
number_format(
|
||||
round($bytes, 4 * $this->arguments['decimals']),
|
||||
(int)$this->arguments['decimals'],
|
||||
$this->arguments['decimalSeparator'],
|
||||
$this->arguments['thousandsSeparator']
|
||||
),
|
||||
$units[$pow]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set argument name to be used as content.
|
||||
*/
|
||||
public function getContentArgumentName(): string
|
||||
{
|
||||
return 'value';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use TYPO3\CMS\Core\Html\HtmlCropper;
|
||||
use TYPO3\CMS\Core\Text\TextCropper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper which can crop (shorten) a text.
|
||||
* Whitespace within the `<f:format.crop>` element will be counted as characters.
|
||||
*
|
||||
* ```
|
||||
* <f:format.crop maxCharacters="10" append="…[more]">
|
||||
* This is some very long text
|
||||
* </f:format.crop>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-crop
|
||||
*/
|
||||
final class CropViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* The output may contain HTML and can not be escaped.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function __construct(
|
||||
private readonly TextCropper $textCropper,
|
||||
private readonly HtmlCropper $htmlCropper,
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('maxCharacters', 'int', 'Place where to truncate the string', true);
|
||||
$this->registerArgument('append', 'string', 'What to append, if truncation happened', false, '…');
|
||||
$this->registerArgument('respectWordBoundaries', 'bool', 'If TRUE and division is in the middle of a word, the remains of that word is removed.', false, true);
|
||||
$this->registerArgument('respectHtml', 'bool', 'If TRUE the cropped string will respect HTML tags and entities. Technically that means, that cropHTML() is called rather than crop()', false, true);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$maxCharacters = (int)$this->arguments['maxCharacters'];
|
||||
$append = (string)$this->arguments['append'];
|
||||
$respectWordBoundaries = (bool)($this->arguments['respectWordBoundaries']);
|
||||
$respectHtml = (bool)$this->arguments['respectHtml'];
|
||||
$stringToTruncate = (string)$this->renderChildren();
|
||||
return $respectHtml
|
||||
? $this->htmlCropper->crop($stringToTruncate, $maxCharacters, $append, $respectWordBoundaries)
|
||||
: $this->textCropper->crop($stringToTruncate, $maxCharacters, $append, $respectWordBoundaries);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper which formats a given float to a currency representation.
|
||||
*
|
||||
* ```
|
||||
* <f:format.currency decimalSeparator="." thousandsSeparator="," decimals="2"
|
||||
* currencySign="$" prependCurrency="true" separateCurrency="false">
|
||||
* 54321
|
||||
* </f:format.currency>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-currency
|
||||
*/
|
||||
final class CurrencyViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Output is escaped already. We must not escape children, to avoid double encoding.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('currencySign', 'string', 'The currency sign, eg $ or €.', false, '');
|
||||
$this->registerArgument('decimalSeparator', 'string', 'The separator for the decimal point.', false, ',');
|
||||
$this->registerArgument('thousandsSeparator', 'string', 'The thousands separator.', false, '.');
|
||||
$this->registerArgument('prependCurrency', 'bool', 'Select if the currency sign should be prepended', false, false);
|
||||
$this->registerArgument('separateCurrency', 'bool', 'Separate the currency sign from the number by a single space, defaults to true due to backwards compatibility', false, true);
|
||||
$this->registerArgument('decimals', 'int', 'Set decimals places.', false, 2);
|
||||
$this->registerArgument('useDash', 'bool', 'Use the dash instead of decimal 00', false, false);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$currencySign = $this->arguments['currencySign'];
|
||||
$decimalSeparator = $this->arguments['decimalSeparator'];
|
||||
$thousandsSeparator = $this->arguments['thousandsSeparator'];
|
||||
$prependCurrency = $this->arguments['prependCurrency'];
|
||||
$separateCurrency = $this->arguments['separateCurrency'];
|
||||
$decimals = (int)$this->arguments['decimals'];
|
||||
$useDash = $this->arguments['useDash'];
|
||||
$floatToFormat = $this->renderChildren();
|
||||
if (empty($floatToFormat)) {
|
||||
$floatToFormat = 0.0;
|
||||
} else {
|
||||
$floatToFormat = (float)$floatToFormat;
|
||||
}
|
||||
$output = number_format($floatToFormat, $decimals, $decimalSeparator, $thousandsSeparator);
|
||||
if ($useDash && $floatToFormat === floor($floatToFormat)) {
|
||||
$output = explode($decimalSeparator, $output)[0] . $decimalSeparator . '—';
|
||||
}
|
||||
if ($currencySign !== '') {
|
||||
$currencySeparator = $separateCurrency ? ' ' : '';
|
||||
if ($prependCurrency === true) {
|
||||
$output = $currencySign . $currencySeparator . $output;
|
||||
} else {
|
||||
$output = $output . $currencySeparator . $currencySign;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Http\ApplicationType;
|
||||
use TYPO3\CMS\Core\Localization\DateFormatter;
|
||||
use TYPO3\CMS\Core\Localization\Locale;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\InvalidArgumentValueException;
|
||||
|
||||
/**
|
||||
* ViewHelper to format an object implementing `\DateTimeInterface` into human-readable output.
|
||||
*
|
||||
* ```
|
||||
* <f:format.date format="Y-m-d H:i">{dateObject}</f:format.date>
|
||||
* <f:format.date format="Y" base="{dateObject}">-1 year</f:format.date>
|
||||
* <f:format.date pattern="dd. MMMM yyyy" locale="de-DE">{dateObject}</f:format.date>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-date
|
||||
* @see https://www.php.net/manual/datetime.format.php
|
||||
* @see \DateTimeInterface
|
||||
*/
|
||||
final class DateViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Needed as child node's output can return a DateTime object which can't be escaped
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
public function __construct(
|
||||
private readonly Context $context
|
||||
) {}
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('date', 'mixed', 'Either an object implementing DateTimeInterface or a string that is accepted by DateTime constructor');
|
||||
$this->registerArgument('format', 'string', 'Format String which is taken to format the Date/Time', false, '');
|
||||
$this->registerArgument('pattern', 'string', 'Format date based on unicode ICO format pattern given see https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax. If both "pattern" and "format" arguments are given, pattern will be used.');
|
||||
$this->registerArgument('locale', 'string', 'A locale format such as "nl-NL" to format the date in a specific locale, if none given, uses the current locale of the current request. Only works when pattern argument is given');
|
||||
$this->registerArgument('base', 'mixed', 'A base time (an object implementing DateTimeInterface or a string) used if $date is a relative date specification. Defaults to current time.');
|
||||
$this->registerArgument('timezone', 'string', 'Timezone for the date');
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$format = $this->arguments['format'] ?? '';
|
||||
$pattern = $this->arguments['pattern'] ?? null;
|
||||
$base = $this->arguments['base'] ?? $this->context->getPropertyFromAspect('date', 'timestamp');
|
||||
if (is_string($base)) {
|
||||
$base = trim($base);
|
||||
}
|
||||
if ($format === '') {
|
||||
$format = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] ?: 'Y-m-d';
|
||||
}
|
||||
$date = $this->renderChildren();
|
||||
if ($date === null) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($date)) {
|
||||
$date = trim($date);
|
||||
}
|
||||
if ($date === '') {
|
||||
$date = $this->context->getPropertyFromAspect('date', 'timestamp', 'now');
|
||||
}
|
||||
if (!$date instanceof \DateTimeInterface) {
|
||||
$base = $base instanceof \DateTimeInterface
|
||||
? (int)$base->format('U')
|
||||
: (int)strtotime((MathUtility::canBeInterpretedAsInteger($base) ? '@' : '') . $base);
|
||||
$dateTimestamp = strtotime((MathUtility::canBeInterpretedAsInteger($date) ? '@' : '') . $date, $base);
|
||||
if ($dateTimestamp === false) {
|
||||
throw new InvalidArgumentValueException('"' . $date . '" could not be converted to a timestamp. Probably due to a parsing error.', 1241722579);
|
||||
}
|
||||
$date = (new \DateTime())->setTimestamp($dateTimestamp);
|
||||
}
|
||||
|
||||
if (!empty($this->arguments['timezone'])) {
|
||||
$timezone = (string)$this->arguments['timezone'];
|
||||
if ($date instanceof \DateTime) {
|
||||
$date->setTimezone(new \DateTimeZone($timezone));
|
||||
} elseif ($date instanceof \DateTimeImmutable) {
|
||||
$date = $date->setTimezone(new \DateTimeZone($timezone));
|
||||
}
|
||||
}
|
||||
|
||||
if ($pattern !== null) {
|
||||
$locale = $this->arguments['locale'] ?? self::resolveLocale($this->renderingContext);
|
||||
return (new DateFormatter())->format($date, $pattern, $locale);
|
||||
}
|
||||
if (str_contains($format, '%')) {
|
||||
// @todo: deprecate this syntax in TYPO3 v13.
|
||||
$locale = $this->arguments['locale'] ?? self::resolveLocale($this->renderingContext);
|
||||
return (new DateFormatter())->strftime($format, $date, $locale);
|
||||
}
|
||||
return $date->format($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set argument name to be used as content.
|
||||
*/
|
||||
public function getContentArgumentName(): string
|
||||
{
|
||||
return 'date';
|
||||
}
|
||||
|
||||
private static function resolveLocale(RenderingContextInterface $renderingContext): Locale
|
||||
{
|
||||
$request = null;
|
||||
if ($renderingContext->hasAttribute(ServerRequestInterface::class)) {
|
||||
$request = $renderingContext->getAttribute(ServerRequestInterface::class);
|
||||
} elseif (($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface) {
|
||||
// @todo: deprecate
|
||||
$request = $GLOBALS['TYPO3_REQUEST'];
|
||||
}
|
||||
if ($request && ApplicationType::fromRequest($request)->isFrontend()) {
|
||||
// Frontend application
|
||||
$siteLanguage = $request->getAttribute('language');
|
||||
|
||||
// Get values from site language
|
||||
if ($siteLanguage !== null) {
|
||||
return $siteLanguage->getLocale();
|
||||
}
|
||||
} elseif (($GLOBALS['BE_USER'] ?? null) instanceof BackendUserAuthentication
|
||||
&& !empty($GLOBALS['BE_USER']->user['lang'])) {
|
||||
return new Locale($GLOBALS['BE_USER']->user['lang']);
|
||||
}
|
||||
return new Locale();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Http\ApplicationType;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to render a string which can contain HTML markup
|
||||
* by passing it to a TYPO3 `parseFunc`. This can sanitize
|
||||
* unwanted HTML tags and attributes, and keep wanted HTML syntax and
|
||||
* take care of link substitution and other parsing.
|
||||
* Either specify a path to the TypoScript setting or set the `parseFunc` options directly.
|
||||
* By default, `lib.parseFunc_RTE` is used to parse the string.
|
||||
*
|
||||
* ```
|
||||
* <f:format.html parseFuncTSPath="lib.myCustomParseFunc">
|
||||
* {$project} is a cool <b>CMS</b> (<a href="https://www.typo3.org">TYPO3</a>).
|
||||
* </f:format.html>
|
||||
* ```
|
||||
*
|
||||
* **Note:** The ViewHelper must not be used in backend context, as it triggers frontend logic.
|
||||
* Instead, use `<f:sanitize.html>` within backend context to secure a given HTML string
|
||||
* or `<f:transform.html>` to parse links in HTML.
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-html
|
||||
* @see https://docs.typo3.org/permalink/t3tsref:parsefunc
|
||||
*/
|
||||
final class HtmlViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Children must not be escaped, to be able to pass {bodytext} directly to it
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
/**
|
||||
* Plain HTML should be returned, no output escaping allowed
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('parseFuncTSPath', 'string', 'Path to the TypoScript parseFunc setup.', false, 'lib.parseFunc_RTE');
|
||||
$this->registerArgument('data', 'mixed', 'Initialize the content object with this set of data. Either an array or object.');
|
||||
$this->registerArgument('current', 'string', 'Initialize the content object with this value for current property.');
|
||||
$this->registerArgument('currentValueKey', 'string', 'Define the value key, used to locate the current value for the content object');
|
||||
$this->registerArgument('table', 'string', 'The table name associated with the "data" argument.', false, '');
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$parseFuncTSPath = $this->arguments['parseFuncTSPath'];
|
||||
$data = $this->arguments['data'];
|
||||
$current = $this->arguments['current'];
|
||||
$currentValueKey = $this->arguments['currentValueKey'];
|
||||
$table = $this->arguments['table'];
|
||||
$request = null;
|
||||
if ($this->renderingContext->hasAttribute(ServerRequestInterface::class)) {
|
||||
$request = $this->renderingContext->getAttribute(ServerRequestInterface::class);
|
||||
}
|
||||
$isBackendRequest = $request instanceof ServerRequestInterface && ApplicationType::fromRequest($request)->isBackend();
|
||||
if ($isBackendRequest) {
|
||||
throw new \RuntimeException(
|
||||
'Using f:format.html in backend context is not allowed. Use f:sanitize.html or f:transform.html instead.',
|
||||
1686813703
|
||||
);
|
||||
}
|
||||
$value = $this->renderChildren() ?? '';
|
||||
// Prepare data array
|
||||
if (is_object($data)) {
|
||||
$data = ObjectAccess::getGettableProperties($data);
|
||||
} elseif (!is_array($data)) {
|
||||
$data = (array)$data;
|
||||
}
|
||||
$contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
$contentObject->setRequest($request);
|
||||
$contentObject->start($data, $table);
|
||||
if ($current !== null) {
|
||||
$contentObject->setCurrentVal($current);
|
||||
} elseif ($currentValueKey !== null && isset($data[$currentValueKey])) {
|
||||
$contentObject->setCurrentVal($data[$currentValueKey]);
|
||||
}
|
||||
$content = $contentObject->parseFunc($value, null, '< ' . $parseFuncTSPath);
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
/**
|
||||
* ViewHelper to apply `html_entity_decode()` to a value,
|
||||
* transforming HTML entity representations back into HTML special characters
|
||||
* (like `"` to `"`).
|
||||
*
|
||||
* ```
|
||||
* <f:format.htmlentitiesDecode>{textWithEntities}</f:format.htmlentitiesDecode>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-htmlentitiesdecode
|
||||
* @see https://www.php.net/html_entity_decode
|
||||
*/
|
||||
final class HtmlentitiesDecodeViewHelper extends AbstractEncodingViewHelper
|
||||
{
|
||||
/**
|
||||
* We accept value and children interchangeably, thus we must disable children escaping.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
/**
|
||||
* If we decode, we must not encode again after that.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('value', 'string', 'string to format');
|
||||
$this->registerArgument('keepQuotes', 'bool', 'If TRUE, single and double quotes won\'t be replaced (sets ENT_NOQUOTES flag).', false, false);
|
||||
$this->registerArgument('encoding', 'string', 'Define the encoding used when converting characters (Default: UTF-8).');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all HTML entities to their applicable characters as needed using PHPs html_entity_decode() function.
|
||||
*
|
||||
* @see https://www.php.net/html_entity_decode
|
||||
*/
|
||||
public function render(): mixed
|
||||
{
|
||||
$value = $this->renderChildren();
|
||||
$encoding = $this->arguments['encoding'];
|
||||
$keepQuotes = $this->arguments['keepQuotes'];
|
||||
if (!is_string($value) && !(is_object($value) && method_exists($value, '__toString'))) {
|
||||
return $value;
|
||||
}
|
||||
if ($encoding === null) {
|
||||
$encoding = self::resolveDefaultEncoding();
|
||||
}
|
||||
$flags = $keepQuotes ? ENT_NOQUOTES : ENT_COMPAT;
|
||||
return html_entity_decode((string)$value, $flags, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set argument name to be used as content.
|
||||
*/
|
||||
public function getContentArgumentName(): string
|
||||
{
|
||||
return 'value';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
/**
|
||||
* ViewHelper to apply `htmlentities()` escaping to a value,
|
||||
* transforming all HTML special characters to entity representations
|
||||
* (like `"` to `"`).
|
||||
*
|
||||
* ```
|
||||
* <f:format.htmlentities>{textWithHtml}</f:format.htmlentities>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-htmlentities
|
||||
* @see https://www.php.net/manual/function.htmlentities.php
|
||||
*/
|
||||
final class HtmlentitiesViewHelper extends AbstractEncodingViewHelper
|
||||
{
|
||||
/**
|
||||
* Output gets encoded by this viewhelper
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeOutput = false;
|
||||
|
||||
/**
|
||||
* This prevents double encoding as the whole output gets encoded at the end
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('value', 'string', 'string to format');
|
||||
$this->registerArgument('keepQuotes', 'bool', 'If TRUE, single and double quotes won\'t be replaced (sets ENT_NOQUOTES flag).', false, false);
|
||||
$this->registerArgument('encoding', 'string', 'Define the encoding used when converting characters (Default: UTF-8');
|
||||
$this->registerArgument('doubleEncode', 'bool', 'If FALSE existing html entities won\'t be encoded, the default is to convert everything.', false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes special characters with their escaped counterparts as needed using PHPs htmlentities() function.
|
||||
*
|
||||
* @see https://www.php.net/manual/function.htmlentities.php
|
||||
*/
|
||||
public function render(): mixed
|
||||
{
|
||||
$value = $this->renderChildren();
|
||||
$encoding = $this->arguments['encoding'];
|
||||
$keepQuotes = $this->arguments['keepQuotes'];
|
||||
$doubleEncode = $this->arguments['doubleEncode'];
|
||||
if (!is_string($value) && !(is_object($value) && method_exists($value, '__toString'))) {
|
||||
return $value;
|
||||
}
|
||||
if ($encoding === null) {
|
||||
$encoding = self::resolveDefaultEncoding();
|
||||
}
|
||||
$flags = $keepQuotes ? ENT_NOQUOTES : ENT_QUOTES;
|
||||
return htmlentities((string)$value, $flags, $encoding, $doubleEncode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set argument name to be used as content.
|
||||
*/
|
||||
public function getContentArgumentName(): string
|
||||
{
|
||||
return 'value';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
|
||||
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* ViewHelper to format a string to specific lengths, by using PHPs `str_pad` function.
|
||||
*
|
||||
* ```
|
||||
* <f:format.padding padLength="10" padString="!" padType="right">TYPO3</f:format.padding>
|
||||
* ```
|
||||
*
|
||||
* @see https://docs.typo3.org/permalink/t3viewhelper:typo3-fluid-format-padding
|
||||
* @see https://www.php.net/manual/en/function.str-pad
|
||||
*/
|
||||
final class PaddingViewHelper extends AbstractViewHelper
|
||||
{
|
||||
/**
|
||||
* Output is escaped already. We must not escape children, to avoid double encoding.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $escapeChildren = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('value', 'string', 'string to format');
|
||||
$this->registerArgument('padLength', 'int', 'Length of the resulting string. If the value of pad_length is negative or less than the length of the input string, no padding takes place.', true);
|
||||
$this->registerArgument('padString', 'string', 'The padding string', false, ' ');
|
||||
$this->registerArgument('padType', 'string', 'Append the padding at this site (Possible values: right,left,both. Default: right)', false, 'right');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad a string to a certain length with another string.
|
||||
*/
|
||||
public function render(): string
|
||||
{
|
||||
$value = $this->renderChildren();
|
||||
$padTypes = [
|
||||
'left' => STR_PAD_LEFT,
|
||||
'right' => STR_PAD_RIGHT,
|
||||
'both' => STR_PAD_BOTH,
|
||||
];
|
||||
$padType = $this->arguments['padType'];
|
||||
if (!isset($padTypes[$padType])) {
|
||||
$padType = 'right';
|
||||
}
|
||||
$value = (string)$value;
|
||||
$padString = (string)$this->arguments['padString'];
|
||||
// mb_str_pad() throws a ValueError on an empty pad string, so return the value unchanged in that case.
|
||||
if ($padString === '') {
|
||||
return $value;
|
||||
}
|
||||
return mb_str_pad($value, (int)$this->arguments['padLength'], $padString, $padTypes[$padType]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly set argument name to be used as content.
|
||||
*/
|
||||
public function getContentArgumentName(): string
|
||||
{
|
||||
return 'value';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user