Skip to content

Commit 210dbac

Browse files
authored
Merge pull request #54 from sitegeist/feature/componentAwareDataStructures
Feature/component aware data structures
2 parents 00a185f + 849be1f commit 210dbac

File tree

5 files changed

+72
-11
lines changed

5 files changed

+72
-11
lines changed

Classes/Fluid/ViewHelper/ComponentRenderer.php

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

33
namespace SMS\FluidComponents\Fluid\ViewHelper;
44

5+
use SMS\FluidComponents\Interfaces\ComponentAware;
56
use SMS\FluidComponents\Utility\ComponentArgumentConverter;
67
use SMS\FluidComponents\Utility\ComponentLoader;
78
use SMS\FluidComponents\Utility\ComponentPrefixer\ComponentPrefixerInterface;
@@ -148,6 +149,12 @@ public function render()
148149
$argumentType = $this->argumentDefinitions[$name]->getType();
149150

150151
$argument = $componentArgumentConverter->convertValueToType($argument, $argumentType);
152+
153+
// Provide component namespace to certain data structures
154+
if ($argument instanceof ComponentAware) {
155+
$argument->setComponentNamespace($this->componentNamespace);
156+
}
157+
151158
$variableContainer->add($name, $argument);
152159
}
153160

Classes/Interfaces/ComponentAware.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace SMS\FluidComponents\Interfaces;
4+
5+
/**
6+
* By implementing ComponentAware in a data structure, fluid
7+
* components will provide the component namespace to the data
8+
* structure when used in a component call so that the data structure
9+
* can behave differently for each component (e. g. by reading
10+
* something from the component's directory)
11+
*/
12+
interface ComponentAware
13+
{
14+
public function setComponentNamespace(string $componentNamespace): void;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace SMS\FluidComponents\Interfaces;
4+
5+
/**
6+
* ConstructibleFromNull defines an alternative constructor
7+
* which initializes the object without any input
8+
*/
9+
interface ConstructibleFromNull
10+
{
11+
/**
12+
* Creates an instance of the class
13+
*
14+
* @return object
15+
*/
16+
public static function fromNull();
17+
}

Classes/Utility/ComponentArgumentConverter.php

+32-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use SMS\FluidComponents\Interfaces\ConstructibleFromExtbaseFile;
77
use SMS\FluidComponents\Interfaces\ConstructibleFromFileInterface;
88
use SMS\FluidComponents\Interfaces\ConstructibleFromInteger;
9+
use SMS\FluidComponents\Interfaces\ConstructibleFromNull;
910
use SMS\FluidComponents\Interfaces\ConstructibleFromString;
1011
use TYPO3\CMS\Core\Resource\File;
1112
use TYPO3\CMS\Core\Resource\FileReference;
@@ -33,6 +34,10 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
3334
ConstructibleFromArray::class,
3435
'fromArray'
3536
],
37+
'NULL' => [
38+
ConstructibleFromNull::class,
39+
'fromNull'
40+
],
3641
FileReference::class => [
3742
ConstructibleFromFileInterface::class,
3843
'fromFileInterface'
@@ -55,6 +60,13 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
5560
],
5661
];
5762

63+
/**
64+
* Runtime cache to speed up conversion checks
65+
*
66+
* @var array
67+
*/
68+
protected $conversionCache = [];
69+
5870
/**
5971
* Adds an interface to specify argument type conversion to list
6072
*
@@ -91,22 +103,32 @@ public function removeConversionInterface(string $fromType): self
91103
*/
92104
public function canTypeBeConvertedToType(string $givenType, string $toType): bool
93105
{
94-
// Check if a constructor interface exists for the given type
95-
if (!isset($this->conversionInterfaces[$givenType])) {
106+
// No need to convert equal types
107+
if ($givenType === $toType) {
96108
return false;
97109
}
98110

111+
// Has this check already been computed?
112+
if (isset($this->conversionCache[$givenType . '|' . $toType])) {
113+
return $this->conversionCache[$givenType . '|' . $toType];
114+
}
115+
116+
// Check if a constructor interface exists for the given type
99117
// Check if the target type is a PHP class
100-
if (!class_exists($toType)) {
101-
return false;
118+
$canBeConverted = false;
119+
if (isset($this->conversionInterfaces[$givenType]) && class_exists($toType)) {
120+
// Check if the target type implements the constructor interface
121+
// required for conversion
122+
$canBeConverted = is_subclass_of(
123+
$toType,
124+
$this->conversionInterfaces[$givenType][0]
125+
);
102126
}
103127

104-
// Check if the target type implements the constructor interface
105-
// required for conversion
106-
return is_subclass_of(
107-
$toType,
108-
$this->conversionInterfaces[$givenType][0]
109-
);
128+
// Add to runtime cache
129+
$this->conversionCache[$givenType . '|' . $toType] = $canBeConverted;
130+
131+
return $canBeConverted;
110132
}
111133

112134
/**

ext_emconf.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
'state' => 'stable',
1010
'uploadfolder' => false,
1111
'clearCacheOnLoad' => false,
12-
'version' => '2.0.1',
12+
'version' => '2.1.0',
1313
'constraints' => [
1414
'depends' => [
1515
'typo3' => '9.5.0-10.9.99',

0 commit comments

Comments
 (0)