|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Buergerstimmende\Newssystem\ViewHelpers;
|
|
|
|
/***************************************************************
|
|
*
|
|
* Copyright notice
|
|
*
|
|
* (c) 2024 Dr. Dieter Porth <info@mobger.de>
|
|
*
|
|
* All rights reserved
|
|
*
|
|
* This script is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* The GNU General Public License can be found at
|
|
* http://www.gnu.org/copyleft/gpl.html.
|
|
*
|
|
* This copyright notice MUST APPEAR in all copies of the script!
|
|
***************************************************************/
|
|
|
|
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
|
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
|
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
|
use TYPO3Fluid\Fluid\Exception;
|
|
|
|
/**
|
|
* The viewhelper buid a convert-variable for a string by using a php-function. The variable contains the result
|
|
* of the conversion. It may be an integer, a string or an array. The list of usable php-functions are restricted.
|
|
* You can use every php-function, if you set the ignoreWarning-flag.
|
|
*
|
|
*
|
|
* Examples which defines nested variables
|
|
* =======================================
|
|
*
|
|
* IMPORTANT: The attribute ``value`` is already defined and the rendered context
|
|
*
|
|
* The nested content will be intepreted as template-content. The defined variable is only accessable in the block.
|
|
* It works similiar to <f:alias map=.... >
|
|
*
|
|
* The following table shows the behavior of the different attribute/value constellations.
|
|
* value set render exist local Result Exception Remark
|
|
* nein nein false ja
|
|
* ja nein false var global
|
|
* nein ja false var global
|
|
* ja ja false var global,
|
|
* rendering visible
|
|
* nein nein true var global,
|
|
* empty rendering lokal-flag ignored
|
|
* ja nein true var lokal,
|
|
* empty rendering
|
|
* nein ja true var global lokal-flag ignored
|
|
* ja ja true var lokal,
|
|
* rendering visible
|
|
*
|
|
* ATTENTION: The order of the parameter for the php-function must be respected within the arrays `prev` and `post`. (see anti-example `implode`)
|
|
*
|
|
* Examples which defines global variables
|
|
* =======================================
|
|
*
|
|
* IMPORTANT: The attribute ``value`` is UNDEFINED or there is no nested content.
|
|
*
|
|
* Default
|
|
* -------
|
|
*
|
|
* ::
|
|
*
|
|
* {newssys:convert(phpFunc:'strtolower',value:'Some Value In A String',as:'lowered')}
|
|
* <newssys:convert phpFunc="strtolower" as="lowered">{beforeConvert}</newssys:convert>
|
|
* {beforeConvert -> newssys:convert(phpFunc:'strtolower',as:'lowered')}
|
|
* <newssys:convert phpFunc="strtolower" as="lowered">{oldconvert}</newssys:convert>
|
|
*
|
|
* The variable ``lowered`` contains the value ``some value in a string``.
|
|
*
|
|
* ====================================
|
|
* The php-function ``implode`` is not allowed for convert, beause the value must be a string and not an array.
|
|
* You can nevertheless use thefunction ``implode`` in the following way.
|
|
*
|
|
* // remembner the attributes post and prev must be arrays.
|
|
* <newssys:convert phpFunc="implode" as="joinString"
|
|
* post="{0:{0:'The world',1:' which is nice',2:' is blue.'}}"
|
|
* ignoreWarning="1"
|
|
* value=","
|
|
* ></newssys:convert>
|
|
*
|
|
* The result should be: 'The world, which is nice, is blue.'
|
|
*
|
|
*
|
|
*/
|
|
final class ConvertViewHelper extends AbstractViewHelper
|
|
{
|
|
/**
|
|
* Output is escaped already. We must not escape children, to avoid double encoding.
|
|
*
|
|
* @var bool
|
|
*/
|
|
protected $escapeChildren = false;
|
|
|
|
protected const ALLOWED_METHOD = [
|
|
'addslashes',
|
|
'bin2hex',
|
|
'chop',
|
|
'chunk_split',
|
|
'convert_uudecode',
|
|
'convert_uuencode',
|
|
'crc32',
|
|
'crypt',
|
|
'explode',
|
|
'hex2bin',
|
|
'html_entity_decode',
|
|
'htmlentities',
|
|
'htmlspecialchars_decode',
|
|
'htmlspecialchars',
|
|
'lcfirst',
|
|
'ltrim',
|
|
'md5',
|
|
'metaphone',
|
|
'nl2br',
|
|
'quoted_printable_decode',
|
|
'quoted_printable_encode',
|
|
'quotemeta',
|
|
'rtrim',
|
|
'sha1',
|
|
'str_contains',
|
|
'str_decrement',
|
|
'str_ends_with',
|
|
'str_getcsv',
|
|
'str_increment',
|
|
'str_pad',
|
|
'str_repeat',
|
|
'str_rot13',
|
|
'str_shuffle',
|
|
'str_split',
|
|
'str_starts_with',
|
|
'str_word_count',
|
|
'strcasecmp',
|
|
'strchr',
|
|
'strcmp',
|
|
'strcoll',
|
|
'strip_tags',
|
|
'stripos',
|
|
'stripslashes',
|
|
'stristr',
|
|
'strlen',
|
|
'strnatcasecmp',
|
|
'strnatcmp',
|
|
'strncasecmp',
|
|
'strncmp',
|
|
'strpbrk',
|
|
'strpos',
|
|
'strrchr',
|
|
'strrev',
|
|
'strripos',
|
|
'strrpos',
|
|
'strstr',
|
|
'strtok',
|
|
'strtolower',
|
|
'strtoupper',
|
|
'substr',
|
|
'trim',
|
|
'ucfirst',
|
|
'ucwords',
|
|
'wordwrap',
|
|
];
|
|
protected const PARAM_VALUE = 'value';
|
|
protected const PARAM_LOKAL = 'local';
|
|
protected const PARAM_PREV = 'prev';
|
|
protected const PARAM_POST = 'post';
|
|
protected const PHP_FUNC = 'phpfunc';
|
|
protected const PARAM_IGNORE_WARNING = 'ignoreWarning';
|
|
protected const PARAM_AS = 'as';
|
|
|
|
use CompileWithRenderStatic;
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public function initializeArguments()
|
|
{
|
|
$this->registerArgument(self::PARAM_VALUE, 'string',
|
|
'Value to assign. If not in arguments then taken from tag content', false, '');
|
|
$this->registerArgument(self::PARAM_LOKAL, 'bool',
|
|
'flag, if the variable works only for the nested content. '.
|
|
'(It only works, if the value is defined in the attribute `value`.)', false, false);
|
|
$this->registerArgument(self::PARAM_PREV, 'array',
|
|
'parameters before string', false, []);
|
|
$this->registerArgument(self::PARAM_POST, 'array',
|
|
'parameters after string', false, []);
|
|
$this->registerArgument(self::PHP_FUNC, 'string',
|
|
'name of php-method with allows usage of a\n\r string|array = function(string) ', true);
|
|
$this->registerArgument(self::PARAM_IGNORE_WARNING, 'string',
|
|
'Usage of a php-function, which is not part of the allowed methods ', false, false);
|
|
$this->registerArgument(self::PARAM_AS, 'string',
|
|
'Name of variable to create', true);
|
|
}
|
|
|
|
/**
|
|
* @param array<mixed> $arguments
|
|
* @param \Closure $renderChildrenClosure
|
|
* @param RenderingContextInterface $renderingContext
|
|
*
|
|
* @return mixed|void
|
|
*/
|
|
public static function renderStatic(
|
|
array $arguments,
|
|
\Closure $renderChildrenClosure,
|
|
RenderingContextInterface $renderingContext
|
|
)
|
|
{
|
|
try {
|
|
$ignoreWarning = [(string)((isset($arguments[self::PARAM_IGNORE_WARNING])) ?
|
|
$arguments[self::PARAM_IGNORE_WARNING] :
|
|
false
|
|
)];
|
|
$flagLokal = ((isset($arguments[self::PARAM_LOKAL]))?
|
|
$arguments[self::PARAM_LOKAL] :
|
|
false
|
|
);
|
|
$flagRender = false;
|
|
if (isset($arguments[self::PARAM_VALUE])) {
|
|
$flagRender = true;
|
|
$test = [
|
|
(string)$arguments[self::PARAM_VALUE],
|
|
];
|
|
} else {
|
|
// the agrument['value'] is missing =>
|
|
// the rendered block contains the value of the variable and will exist globally
|
|
$flagLokal = false;
|
|
$test = [
|
|
$renderChildrenClosure(),
|
|
];
|
|
}
|
|
$resolveValue = $test[0];
|
|
$phpFunction = (string)$arguments[self::PHP_FUNC];
|
|
$prev = ((isset($arguments[self::PARAM_PREV])) ?
|
|
$arguments[self::PARAM_PREV] :
|
|
[]
|
|
);
|
|
$post = ((isset($arguments[self::PARAM_POST])) ?
|
|
$arguments[self::PARAM_POST] :
|
|
[]
|
|
);
|
|
if ((!is_array($prev)) ||
|
|
(!is_array($post))
|
|
) {
|
|
throw new Exception(
|
|
'The parameters `prev` [' . print_r($prev, true) .
|
|
'] and/or `post` [' . print_r($post, true) . '] are not defined as in an array. ' .
|
|
'The arguments of the viewhelper are: ' . print_r($arguments, true),
|
|
1715246271
|
|
);
|
|
}
|
|
if ((!isset($arguments[self::PARAM_AS])) ||
|
|
(empty(trim($arguments[self::PARAM_AS])))
|
|
) {
|
|
throw new Exception(
|
|
'The name of the new variable is not correctly defined in `as`. ' .
|
|
'The current value is [' . print_r($arguments[self::PARAM_AS], true) . '].' .
|
|
'The arguments of the viewhelper are: ' . print_r($arguments, true),
|
|
1715247382
|
|
);
|
|
|
|
}
|
|
$resolveVariable = trim($arguments[self::PARAM_AS]);
|
|
if (($ignoreWarning) ||
|
|
(in_array($phpFunction, self::ALLOWED_METHOD))
|
|
) {
|
|
$result = array_merge($prev, $test, $post);
|
|
if (is_callable($phpFunction)) {
|
|
$resolveValue = $phpFunction(...$result);
|
|
}
|
|
|
|
} else {
|
|
throw new Exception(
|
|
'The method `' . $phpFunction . '` with the parameters `prev` [' . print_r($prev, true) .
|
|
'] and/or `post` [' . print_r($post, true) . '] is not callable or not allowed. ' .
|
|
'(Remark: The parameter `ignoreWarning` has the value: ' . ($ignoreWarning ? 'true' : 'false[default]') . '.)' .
|
|
'The arguments of the viewhelper are: ' . print_r($arguments, true),
|
|
1715246896
|
|
);
|
|
}
|
|
$renderingContext->getVariableProvider()->add($arguments[self::PARAM_AS], $resolveValue);
|
|
} catch (\Exception $e) {
|
|
throw new Exception(
|
|
'An unexpected error occurs. Check the name of your php-method [' . $phpFunction . ']. ' .
|
|
'Check the order of your parameters in the arrays `prev` [' . print_r($prev, true) .
|
|
'] and/or `post` [' . print_r($post, true) . ']. ' .
|
|
'The arguments of the viewhelper are: ' . print_r($arguments, true),
|
|
1715246453
|
|
);
|
|
}
|
|
|
|
if ($flagLokal) {
|
|
$res = (string) $renderChildrenClosure();
|
|
$renderingContext->getVariableProvider()->remove($arguments[self::PARAM_AS]);
|
|
return $res;
|
|
} else if ($flagRender) {
|
|
$res = (string) $renderChildrenClosure();
|
|
return $res;
|
|
}
|
|
}
|
|
}
|