Я использую TYPO3Fluid для своего пользовательского (автономного) приложения (без TYPO3 CMS).
Мой пользовательский inArray-ViewHelper не работает должным образом.
При первом вызове страницы онкажется, игнорируется (никакой код не выполняется внутри viewhelper). Но при втором вызове страницы viewhelper выполняется и работает (надеюсь) как и ожидалось.
Кроме того, viewhelper работает, только если включено кэширование, если отключено, он просто возвращает else-часть.
<?php
namespace TYPO3Fluid\Fluid\ViewHelpers;
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
class InArrayViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper {
/**
* 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() {
parent::initializeArguments();
$this->registerArgument('haystack', 'mixed', 'View helper haystack ', TRUE);
$this->registerArgument('needle', 'string', 'View helper needle', TRUE);
}
/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return mixed
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext){
$needle = $arguments['needle'];
$haystack = $arguments['haystack'];
if(!is_array($haystack)) {
return $this->renderElseChild();
}else {
if (in_array($needle, $haystack)) {
if (isset($arguments['then'])) {
return $arguments['then'];
}
if (isset($arguments['__thenClosure'])) {
return $arguments['__thenClosure']();
}
} elseif (!empty($arguments['__elseClosures'])) {
$elseIfClosures = isset($arguments['__elseifClosures']) ? $arguments['__elseifClosures'] : [];
return static::evaluateElseClosures($arguments['__elseClosures'], $elseIfClosures, $renderingContext);
} elseif (array_key_exists('else', $arguments)){
return $arguments['else'];
}
return '';
}
}
/**
* @param array $closures
* @param array $conditionClosures
* @param RenderingContextInterface $renderingContext
* @return string
*/
private static function evaluateElseClosures(array $closures, array $conditionClosures, RenderingContextInterface $renderingContext)
{
foreach ($closures as $elseNodeIndex => $elseNodeClosure) {
if (!isset($conditionClosures[$elseNodeIndex])) {
return $elseNodeClosure();
} else {
if ($conditionClosures[$elseNodeIndex]()) {
return $elseNodeClosure();
}
}
}
return '';
}
}
У кого-нибудь есть идея, чтобы это исправить? Или кто-нибудь знает лучшее решение для inArray?
EDIT:
Хорошо, как сказано в документации, renderStatic () нельзя использовать для viewhelper, которому нужен доступ к своим потомкам. Так что я не могу использовать renderStatic () здесь. Я попытался использовать render (), который доставил мне больше проблем, потому что тогда первая загрузка страницы дала 500! Поэтому я перешел на compile () как метод рендеринга. Теперь я могу использовать мой viewhelper в качестве аргумента внутри условия if. Это нормально и работает.
Новые проблемы:
- Песчаный Я не могу использовать его внутри условия inline-if-условие! Грустно!
- Приходится использовать -Tag вокруг моего состояния, в других случаях результат будет ложным каждый раз.
Теперь окно справки выглядит так
<?php
namespace TYPO3Fluid\Fluid\ViewHelpers;
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class InArrayViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper {
use CompileWithRenderStatic;
public function initializeArguments() {
parent::initializeArguments();
$this->registerArgument('haystack', 'mixed', 'View helper haystack ', TRUE);
$this->registerArgument('needle', 'string', 'View helper needle', TRUE);
}
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
return in_array($arguments['needle'], $arguments['haystack']);
}
public function compile(
$argumentsName,
$closureName,
&$initializationPhpCode,
ViewHelperNode $node,
TemplateCompiler $compiler
) {
return 'in_array('.$argumentsName.'[\'needle\'],'. $argumentsName.'[\'haystack\'])';
}
}
РЕДАКТИРОВАТЬ2:
Я сделал некоторые изменения в compile () - возможно, это сработает.
EDIT 3:
Я попытался переписать класс IfViewHelper. Но это, к сожалению, не работает. Значения и результат in_array такие же, как ожидалось, но отображаемое значение всегда ложно.
<?php
namespace TYPO3Fluid\Fluid\ViewHelpers;
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
class InArrayViewHelper extends \TYPO3Fluid\Fluid\ViewHelpers\IfViewHelper {
use CompileWithRenderStatic;
public function initializeArguments() {
parent::initializeArguments();
$this->registerArgument('haystack', 'mixed', 'View helper haystack ', TRUE);
$this->registerArgument('needle', 'string', 'View helper needle', TRUE);
}
/**
* @param array $arguments
* @param RenderingContextInterface $renderingContext
* @return bool
*/
public static function verdict(array $arguments, RenderingContextInterface $renderingContext)
{
return in_array($arguments['needle'], $arguments['haystack']);
}
}
Поэтому я использую второй код и отключаю кеш вокруг условия. Работает, но без возможности использовать его в inline-if-условии.