-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Add compatibility layer to basically all ViewHelpers
Adds a massive number of backwards/cross compatibility handlers, because Fluid decided to introduce a large number of completely unnecessary breaking changes in v4, because "it's cleaner" and apparently nobody cares about devs anymore.
- Loading branch information
1 parent
5b3ef99
commit 9cab935
Showing
140 changed files
with
577 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
namespace FluidTYPO3\Vhs\Traits; | ||
|
||
/* | ||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.md file that was distributed with this source code. | ||
*/ | ||
|
||
use TYPO3\CMS\Core\Utility\VersionNumberUtility; | ||
|
||
trait ArgumentOverride | ||
{ | ||
protected function overrideArgument( | ||
$name, | ||
$type, | ||
$description, | ||
$required = false, | ||
$defaultValue = null, | ||
$escape = null | ||
) { | ||
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '13.4', '>=')) { | ||
return parent::registerArgument($name, $type, $description, $required, $defaultValue, $escape); | ||
} | ||
return parent::overrideArgument($name, $type, $description, $required, $defaultValue, $escape); | ||
} | ||
} |
184 changes: 184 additions & 0 deletions
184
Classes/Traits/CompileWithContentArgumentAndRenderStatic.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
<?php | ||
namespace FluidTYPO3\Vhs\Traits; | ||
|
||
/* | ||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.md file that was distributed with this source code. | ||
*/ | ||
|
||
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler; | ||
use TYPO3Fluid\Fluid\Core\Compiler\ViewHelperCompiler; | ||
use TYPO3Fluid\Fluid\Core\Exception; | ||
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\ViewHelperNode; | ||
|
||
/** | ||
* Class CompilableWithContentArgumentAndRenderStatic | ||
* | ||
* Provides default methods for rendering and compiling | ||
* any ViewHelper that conforms to the `renderStatic` | ||
* method pattern but has the added common use case that | ||
* an argument value must be checked and used instead of | ||
* the normal render children closure, if that named | ||
* argument is specified and not empty. | ||
*/ | ||
trait CompileWithContentArgumentAndRenderStatic | ||
{ | ||
/** | ||
* Name of variable that contains the value to use | ||
* instead of render children closure, if specified. | ||
* If no name is provided here, the first variable | ||
* registered in `initializeArguments` of the ViewHelper | ||
* will be used. | ||
* | ||
* Note: it is significantly better practice defining | ||
* this property in your ViewHelper class and so fix it | ||
* to one particular argument instead of resolving, | ||
* especially when your ViewHelper is called multiple | ||
* times within an uncompiled template! | ||
* | ||
* This property cannot be directly set in consuming | ||
* ViewHelper, instead set the property in ViewHelper | ||
* constructor '__construct()', for example with | ||
* $this->contentArgumentName = 'explicitlyToUseArgumentName'; | ||
* | ||
* Another possible way would be to override the method | ||
* 'resolveContentArgumentName()' and return the name. | ||
* | ||
* public function resolveContentArgumentName() | ||
* { | ||
* return 'explicitlyToUseArgumentName'; | ||
* } | ||
* | ||
* Note: Setting this through 'initializeArguments()' will | ||
* not work as expected, and other methods should be | ||
* avoided to override this. | ||
* | ||
* Following test ViewHelpers are tested and demonstrates | ||
* that the setting posibillities works. | ||
* | ||
* @var string | ||
*/ | ||
protected $contentArgumentName; | ||
|
||
/** | ||
* Default render method to render ViewHelper with | ||
* first defined optional argument as content. | ||
* | ||
* @return mixed Rendered result | ||
* @api | ||
*/ | ||
public function render() | ||
{ | ||
return static::renderStatic( | ||
$this->arguments, | ||
$this->buildRenderChildrenClosure(), | ||
$this->renderingContext, | ||
); | ||
} | ||
|
||
/** | ||
* @param string $argumentsName | ||
* @param string $closureName | ||
* @param string $initializationPhpCode | ||
* @param ViewHelperNode $node | ||
* @param TemplateCompiler $compiler | ||
* @return string | ||
*/ | ||
public function compile( | ||
$argumentsName, | ||
$closureName, | ||
&$initializationPhpCode, | ||
ViewHelperNode $node, | ||
TemplateCompiler $compiler | ||
) { | ||
[$initialization, $execution] = ViewHelperCompiler::getInstance()->compileWithCallToStaticMethod( | ||
$this, | ||
$argumentsName, | ||
$closureName, | ||
ViewHelperCompiler::RENDER_STATIC, | ||
static::class | ||
); | ||
$contentArgumentName = $this->resolveContentArgumentName(); | ||
$initializationPhpCode .= sprintf( | ||
'%s = (%s[\'%s\'] !== null) ? function() use (%s) { return %s[\'%s\']; } : %s;', | ||
$closureName, | ||
$argumentsName, | ||
$contentArgumentName, | ||
$argumentsName, | ||
$argumentsName, | ||
$contentArgumentName, | ||
$closureName | ||
); | ||
$initializationPhpCode .= $initialization; | ||
return $execution; | ||
} | ||
|
||
/** | ||
* Helper which is mostly needed when calling renderStatic() from within | ||
* render(). | ||
* | ||
* No public API yet. | ||
* | ||
* @return \Closure | ||
*/ | ||
protected function buildRenderChildrenClosure() | ||
{ | ||
$argumentName = $this->resolveContentArgumentName(); | ||
$arguments = $this->arguments; | ||
if (!empty($argumentName) && isset($arguments[$argumentName])) { | ||
$renderChildrenClosure = function () use ($arguments, $argumentName) { | ||
return $arguments[$argumentName]; | ||
}; | ||
} else { | ||
$self = clone $this; | ||
$renderChildrenClosure = function () use ($self) { | ||
return $self->renderChildren(); | ||
}; | ||
} | ||
return $renderChildrenClosure; | ||
} | ||
|
||
/** | ||
* Helper method which triggers the rendering of everything between the | ||
* opening and the closing tag. | ||
* | ||
* @return mixed The finally rendered child nodes. | ||
* @api | ||
*/ | ||
public function renderChildren() | ||
{ | ||
if ($this->renderChildrenClosure !== null) { | ||
$closure = $this->renderChildrenClosure; | ||
return $closure(); | ||
} | ||
return $this->viewHelperNode->evaluateChildNodes($this->renderingContext); | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function resolveContentArgumentName() | ||
{ | ||
if (empty($this->contentArgumentName)) { | ||
$registeredArguments = $this->prepareArguments(); | ||
foreach ($registeredArguments as $registeredArgument) { | ||
if (!$registeredArgument->isRequired()) { | ||
$this->contentArgumentName = $registeredArgument->getName(); | ||
return $this->contentArgumentName; | ||
} | ||
} | ||
throw new Exception( | ||
sprintf('Attempting to compile %s failed. Chosen compile method requires that ViewHelper has ' . | ||
'at least one registered and optional argument', __CLASS__) | ||
); | ||
} | ||
return $this->contentArgumentName; | ||
} | ||
|
||
public function getContentArgumentName(): ?string | ||
{ | ||
return $this->resolveContentArgumentName(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
namespace FluidTYPO3\Vhs\Traits; | ||
|
||
/* | ||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.md file that was distributed with this source code. | ||
*/ | ||
|
||
/** | ||
* Class CompilableWithRenderStatic | ||
* | ||
* Provides default methods for rendering and compiling | ||
* any ViewHelper that conforms to the `renderStatic` | ||
* method pattern. | ||
*/ | ||
trait CompileWithRenderStatic | ||
{ | ||
/** | ||
* Default render method - simply calls renderStatic() with a | ||
* prepared set of arguments. | ||
* | ||
* @return mixed Rendered result | ||
* @api | ||
*/ | ||
public function render() | ||
{ | ||
return static::renderStatic( | ||
$this->arguments, | ||
$this->buildRenderChildrenClosure(), | ||
$this->renderingContext, | ||
); | ||
} | ||
|
||
/** | ||
* @return \Closure | ||
*/ | ||
abstract protected function buildRenderChildrenClosure(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
namespace FluidTYPO3\Vhs\Traits; | ||
|
||
/* | ||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later. | ||
* | ||
* For the full copyright and license information, please read the | ||
* LICENSE.md file that was distributed with this source code. | ||
*/ | ||
|
||
use TYPO3\CMS\Core\Utility\VersionNumberUtility; | ||
|
||
trait TagViewHelperCompatibility | ||
{ | ||
/** | ||
* Register a new tag attribute. Tag attributes are all arguments which will be directly appended to a tag if you | ||
* call $this->initializeTag() | ||
* | ||
* @param string $name Name of tag attribute | ||
* @param string $type Type of the tag attribute | ||
* @param string $description Description of tag attribute | ||
* @param bool $required set to true if tag attribute is required. Defaults to false. | ||
* @param mixed $defaultValue Optional, default value of attribute if one applies | ||
* @return void | ||
* @api | ||
*/ | ||
protected function registerTagAttribute($name, $type, $description, $required = false, $defaultValue = null) | ||
{ | ||
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '13.4', '>=')) { | ||
$this->registerArgument($name, $type, $description, $required, $defaultValue); | ||
return; | ||
} | ||
parent::registerTagAttribute($name, $type, $description, $required, $defaultValue); | ||
} | ||
|
||
/** | ||
* Registers all standard HTML universal attributes. | ||
* Should be used inside registerArguments(); | ||
* | ||
* @return void | ||
* @api | ||
*/ | ||
protected function registerUniversalTagAttributes() | ||
{ | ||
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '13.4', '>=')) { | ||
return; | ||
} | ||
$this->registerTagAttribute('class', 'string', 'CSS class(es) for this element'); | ||
$this->registerTagAttribute( | ||
'dir', | ||
'string', | ||
'Text direction for this HTML element. Allowed strings: "ltr" (left to right), "rtl" (right to left)' | ||
); | ||
$this->registerTagAttribute('id', 'string', 'Unique (in this file) identifier for this HTML element.'); | ||
$this->registerTagAttribute( | ||
'lang', | ||
'string', | ||
'Language for this element. Use short names specified in RFC 1766' | ||
); | ||
$this->registerTagAttribute('style', 'string', 'Individual CSS styles for this element'); | ||
$this->registerTagAttribute('title', 'string', 'Tooltip text of element'); | ||
$this->registerTagAttribute('accesskey', 'string', 'Keyboard shortcut to access this element'); | ||
$this->registerTagAttribute('tabindex', 'integer', 'Specifies the tab order of this element'); | ||
$this->registerTagAttribute('onclick', 'string', 'JavaScript evaluated for the onclick event'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.