Skip to content

Commit ba5ae02

Browse files
authored
Merge pull request #86 from sitegeist/task/typo311Compatibility
Make extension compatible to TYPO3 v11
2 parents 4bc3bf2 + 6b7f91b commit ba5ae02

15 files changed

+381
-127
lines changed

.ecrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
".Build",
99
".git",
1010
".DS_Store",
11-
".xsd"
11+
".xsd",
12+
"var/"
1213
],
1314
"AllowedContentTypes": [],
1415
"PassedFiles": [],

.github/workflows/tests.yml

+43-42
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,12 @@ jobs:
4747
strategy:
4848
max-parallel: 2
4949
matrix:
50-
php-versions: [7.4, 7.3, 7.2]
51-
typo3-versions: [11.0, 10.4, 9.5]
50+
php-versions: [7.4, 8.0]
51+
typo3-versions: [10, 11]
5252
exclude:
5353
-
54-
php-versions: 7.3
55-
typo3-versions: 11.0
56-
-
57-
php-versions: 7.2
58-
typo3-versions: 11.0
54+
php-versions: 8.0
55+
typo3-versions: 10
5956

6057
name: Unit (PHP ${{ matrix.php-versions }}, TYPO3 ${{ matrix.typo3-versions }})
6158
steps:
@@ -84,38 +81,42 @@ jobs:
8481
name: Automated Unit Testing
8582
run: composer test:unit
8683

87-
integrationtest:
88-
runs-on: ubuntu-latest
89-
90-
strategy:
91-
max-parallel: 2
92-
matrix:
93-
php-versions: [7.4, 7.3, 7.2]
94-
typo3-versions: [9.5]
95-
96-
name: Integration (PHP ${{ matrix.php-versions }}, TYPO3 ${{ matrix.typo3-versions }})
97-
steps:
98-
-
99-
uses: actions/checkout@v2
100-
101-
-
102-
name: Setup PHP
103-
uses: shivammathur/setup-php@v2
104-
with:
105-
php-version: ${{ matrix.php-versions }}
106-
extensions: intl, mbstring, pdo_sqlite
107-
108-
-
109-
name: Cache composer dependencies
110-
uses: actions/cache@v1
111-
with:
112-
path: ~/.composer/cache
113-
key: php-${{ matrix.php-versions }}-typo3-${{ matrix.typo3-versions }}
114-
115-
-
116-
name: Install composer dependencies
117-
run: composer require typo3/minimal "^${{ matrix.typo3-versions }}" --prefer-dist --no-progress --no-suggest
118-
119-
-
120-
name: Automated Integration Testing
121-
run: composer test:integration
84+
# integrationtest:
85+
# runs-on: ubuntu-latest
86+
87+
# strategy:
88+
# max-parallel: 2
89+
# matrix:
90+
# php-versions: [7.4, 8.0]
91+
# typo3-versions: [10, 11]
92+
# exclude:
93+
# -
94+
# php-versions: 8.0
95+
# typo3-versions: 10
96+
97+
# name: Integration (PHP ${{ matrix.php-versions }}, TYPO3 ${{ matrix.typo3-versions }})
98+
# steps:
99+
# -
100+
# uses: actions/checkout@v2
101+
102+
# -
103+
# name: Setup PHP
104+
# uses: shivammathur/setup-php@v2
105+
# with:
106+
# php-version: ${{ matrix.php-versions }}
107+
# extensions: intl, mbstring, pdo_sqlite
108+
109+
# -
110+
# name: Cache composer dependencies
111+
# uses: actions/cache@v1
112+
# with:
113+
# path: ~/.composer/cache
114+
# key: php-${{ matrix.php-versions }}-typo3-${{ matrix.typo3-versions }}
115+
116+
# -
117+
# name: Install composer dependencies
118+
# run: composer require typo3/minimal "^${{ matrix.typo3-versions }}" --prefer-dist --no-progress --no-suggest
119+
120+
# -
121+
# name: Automated Integration Testing
122+
# run: composer test:integration

Classes/Fluid/ViewHelper/ViewHelperResolver.php Classes/Fluid/ViewHelper/AbstractComponentResolver.php

+3-28
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,12 @@
33
namespace SMS\FluidComponents\Fluid\ViewHelper;
44

55
use SMS\FluidComponents\Utility\ComponentLoader;
6-
use TYPO3\CMS\Core\Utility\GeneralUtility;
6+
use TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver;
77
use TYPO3Fluid\Fluid\Core\Parser\Exception as ParserException;
8-
use SMS\FluidComponents\Fluid\ViewHelper\ComponentRenderer;
98

10-
class ViewHelperResolver extends \TYPO3\CMS\Fluid\Core\ViewHelper\ViewHelperResolver
9+
abstract class AbstractComponentResolver extends ViewHelperResolver
1110
{
12-
/**
13-
* @param string $viewHelperClassName
14-
* @return \TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInterface
15-
*/
16-
public function createViewHelperInstanceFromClassName($viewHelperClassName)
17-
{
18-
if (class_exists($viewHelperClassName, true)) {
19-
return $this->getObjectManager()->get($viewHelperClassName);
20-
} else {
21-
// Redirect all components to special ViewHelper ComponentRenderer
22-
$componentRenderer = $this->getObjectManager()->get(ComponentRenderer::class);
23-
24-
$componentRenderer->setComponentNamespace($viewHelperClassName);
25-
26-
return $componentRenderer;
27-
}
28-
}
11+
abstract protected function getComponentLoader(): ComponentLoader;
2912

3013
/**
3114
* Resolves a ViewHelper class name by namespace alias and
@@ -107,12 +90,4 @@ protected function generateViewHelperClassName($resolvedViewHelperClassName)
10790
{
10891
return implode('\\', array_map('ucfirst', explode('.', $resolvedViewHelperClassName)));
10992
}
110-
111-
/**
112-
* @return ComponentLoader
113-
*/
114-
protected function getComponentLoader()
115-
{
116-
return GeneralUtility::makeInstance(ComponentLoader::class);
117-
}
11893
}

Classes/Fluid/ViewHelper/ComponentRenderer.php

+62-35
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SMS\FluidComponents\Fluid\ViewHelper;
44

5+
use Psr\Container\ContainerInterface;
56
use SMS\FluidComponents\Interfaces\ComponentAware;
67
use SMS\FluidComponents\Utility\ComponentArgumentConverter;
78
use SMS\FluidComponents\Utility\ComponentLoader;
@@ -10,9 +11,11 @@
1011
use SMS\FluidComponents\Utility\ComponentSettings;
1112
use SMS\FluidComponents\ViewHelpers\ComponentViewHelper;
1213
use SMS\FluidComponents\ViewHelpers\ParamViewHelper;
14+
use TYPO3\CMS\Core\Configuration\Features;
1315
use TYPO3\CMS\Core\Utility\GeneralUtility;
1416
use TYPO3\CMS\Extbase\Object\ObjectManager;
1517
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
18+
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
1619
use TYPO3Fluid\Fluid\Core\Compiler\TemplateCompiler;
1720
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\BooleanNode;
1821
use TYPO3Fluid\Fluid\Core\Parser\SyntaxTree\EscapingNode;
@@ -22,7 +25,6 @@
2225
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
2326
use TYPO3Fluid\Fluid\Core\ViewHelper\ArgumentDefinition;
2427
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
25-
use TYPO3\CMS\Core\Configuration\Features;
2628

2729
class ComponentRenderer extends AbstractViewHelper
2830
{
@@ -78,6 +80,44 @@ class ComponentRenderer extends AbstractViewHelper
7880
*/
7981
protected $escapeChildren = false;
8082

83+
/**
84+
* @var ComponentLoader
85+
*/
86+
protected ComponentLoader $componentLoader;
87+
88+
/**
89+
* @var ComponentSettings
90+
*/
91+
protected ComponentSettings $componentSettings;
92+
93+
/**
94+
* @var ComponentArgumentConverter
95+
*/
96+
protected ComponentArgumentConverter $componentArgumentConverter;
97+
98+
/**
99+
* @var ContainerInterface
100+
*/
101+
protected ContainerInterface $container;
102+
103+
/**
104+
* @param ComponentLoader $componentLoader
105+
* @param ComponentSettings $componentSettings
106+
* @param ComponentArgumentConverter $componentArgumentConverter
107+
* @param ContainerInterface $container
108+
*/
109+
public function __construct(
110+
ComponentLoader $componentLoader,
111+
ComponentSettings $componentSettings,
112+
ComponentArgumentConverter $componentArgumentConverter,
113+
ContainerInterface $container
114+
) {
115+
$this->componentLoader = $componentLoader;
116+
$this->componentSettings = $componentSettings;
117+
$this->componentArgumentConverter = $componentArgumentConverter;
118+
$this->container = $container;
119+
}
120+
81121
/**
82122
* Sets the namespace of the component the viewhelper should render
83123
*
@@ -129,7 +169,7 @@ public function getComponentPrefix()
129169
public function render()
130170
{
131171
// Create a new rendering context for the component file
132-
$renderingContext = GeneralUtility::makeInstance(RenderingContext::class);
172+
$renderingContext = $this->getRenderingContext();
133173
if ($this->renderingContext->getControllerContext()) {
134174
$renderingContext->setControllerContext($this->renderingContext->getControllerContext());
135175
}
@@ -147,14 +187,13 @@ public function render()
147187
'class' => $this->getComponentClass(),
148188
'prefix' => $this->getComponentPrefix(),
149189
]);
150-
$variableContainer->add('settings', $this->getComponentSettings());
190+
$variableContainer->add('settings', $this->componentSettings);
151191

152192
// Provide supplied arguments from component call to renderer
153-
$componentArgumentConverter = $this->getComponentArgumentConverter();
154193
foreach ($this->arguments as $name => $argument) {
155194
$argumentType = $this->argumentDefinitions[$name]->getType();
156195

157-
$argument = $componentArgumentConverter->convertValueToType($argument, $argumentType);
196+
$argument = $this->componentArgumentConverter->convertValueToType($argument, $argumentType);
158197

159198
// Provide component namespace to certain data structures
160199
if ($argument instanceof ComponentAware) {
@@ -171,8 +210,7 @@ public function render()
171210

172211
// Initialize component rendering template
173212
if (!isset($this->parsedTemplate)) {
174-
$componentLoader = $this->getComponentLoader();
175-
$componentFile = $componentLoader->findComponent($this->componentNamespace);
213+
$componentFile = $this->componentLoader->findComponent($this->componentNamespace);
176214

177215
$this->parsedTemplate = $renderingContext->getTemplateParser()->getOrParseAndStoreTemplate(
178216
$this->getTemplateIdentifier($componentFile),
@@ -314,7 +352,6 @@ public function validateAdditionalArguments(array $arguments)
314352
*/
315353
public function validateArguments()
316354
{
317-
$componentArgumentConverter = $this->getComponentArgumentConverter();
318355
$argumentDefinitions = $this->prepareArguments();
319356
foreach ($argumentDefinitions as $argumentName => $registeredArgument) {
320357
if ($this->hasArgument($argumentName)) {
@@ -324,7 +361,7 @@ public function validateArguments()
324361
if ($value !== $defaultValue && $type !== 'mixed') {
325362
$givenType = is_object($value) ? get_class($value) : gettype($value);
326363
if (!$this->isValidType($type, $value)
327-
&& !$componentArgumentConverter->canTypeBeConvertedToType($givenType, $type)
364+
&& !$this->componentArgumentConverter->canTypeBeConvertedToType($givenType, $type)
328365
) {
329366
throw new \InvalidArgumentException(
330367
'The argument "' . $argumentName . '" was registered with type "' . $type . '", but is of type "' .
@@ -344,10 +381,9 @@ public function validateArguments()
344381
*/
345382
protected function initializeComponentParams()
346383
{
347-
$renderingContext = GeneralUtility::makeInstance(RenderingContext::class);
384+
$renderingContext = $this->getRenderingContext();
348385

349-
$componentLoader = $this->getComponentLoader();
350-
$componentFile = $componentLoader->findComponent($this->componentNamespace);
386+
$componentFile = $this->componentLoader->findComponent($this->componentNamespace);
351387

352388
// Parse component template without using the cache
353389
$parsedTemplate = $renderingContext->getTemplateParser()->parse(
@@ -376,7 +412,6 @@ protected function initializeComponentParams()
376412
);
377413

378414
// Register argument definitions from parameter viewhelpers
379-
$componentArgumentConverter = $this->getComponentArgumentConverter();
380415
foreach ($paramNodes as $paramNode) {
381416
$param = [];
382417
foreach ($paramNode->getArguments() as $argumentName => $argumentNode) {
@@ -399,15 +434,15 @@ protected function initializeComponentParams()
399434
}
400435

401436
// Resolve type aliases
402-
$param['type'] = $componentArgumentConverter->resolveTypeAlias($param['type']);
437+
$param['type'] = $this->componentArgumentConverter->resolveTypeAlias($param['type']);
403438

404439
// Enforce boolean node, see implementation in ViewHelperNode::rewriteBooleanNodesInArgumentsObjectTree()
405440
if ($param['type'] === 'boolean' || $param['type'] === 'bool') {
406441
$param['default'] = BooleanNode::convertToBoolean($param['default'], $renderingContext);
407442
// Make sure that default value for object parameters is either a valid object or null
408443
} elseif (class_exists($param['type']) &&
409444
!$param['default'] instanceof $param['type'] &&
410-
!$componentArgumentConverter->canTypeBeConvertedToType(gettype($param['default']), $param['type'])
445+
!$this->componentArgumentConverter->canTypeBeConvertedToType(gettype($param['default']), $param['type'])
411446
) {
412447
$param['default'] = null;
413448
}
@@ -489,7 +524,11 @@ protected function getComponentPrefixer()
489524
$componentPrefixerClass = GenericComponentPrefixer::class;
490525
}
491526

492-
$componentPrefixer = GeneralUtility::makeInstance($componentPrefixerClass);
527+
if ($this->container->has($componentPrefixerClass)) {
528+
$componentPrefixer = $this->container->get($componentPrefixerClass);
529+
} else {
530+
$componentPrefixer = GeneralUtility::makeInstance($componentPrefixerClass);
531+
}
493532

494533
if (!($componentPrefixer instanceof ComponentPrefixerInterface)) {
495534
throw new Exception(sprintf(
@@ -505,27 +544,15 @@ protected function getComponentPrefixer()
505544
}
506545

507546
/**
508-
* @return ComponentLoader
509-
*/
510-
protected function getComponentLoader(): ComponentLoader
511-
{
512-
return GeneralUtility::makeInstance(ComponentLoader::class);
513-
}
514-
515-
/**
516-
* @return ComponentSettings
517-
*/
518-
protected function getComponentSettings(): ComponentSettings
519-
{
520-
return GeneralUtility::makeInstance(ComponentSettings::class);
521-
}
522-
523-
/**
524-
* @return ComponentArgumentConverter
547+
* @return RenderingContext
525548
*/
526-
protected function getComponentArgumentConverter(): ComponentArgumentConverter
549+
protected function getRenderingContext(): RenderingContext
527550
{
528-
return GeneralUtility::makeInstance(ComponentArgumentConverter::class);
551+
if ($this->container->has(RenderingContextFactory::class)) {
552+
return $this->container->get(RenderingContextFactory::class)->create();
553+
} else {
554+
return GeneralUtility::makeInstance(RenderingContext::class);
555+
}
529556
}
530557

531558
/**

0 commit comments

Comments
 (0)