6
6
use SMS \FluidComponents \Interfaces \ConstructibleFromExtbaseFile ;
7
7
use SMS \FluidComponents \Interfaces \ConstructibleFromFileInterface ;
8
8
use SMS \FluidComponents \Interfaces \ConstructibleFromInteger ;
9
+ use SMS \FluidComponents \Interfaces \ConstructibleFromNull ;
9
10
use SMS \FluidComponents \Interfaces \ConstructibleFromString ;
10
11
use TYPO3 \CMS \Core \Resource \File ;
11
12
use TYPO3 \CMS \Core \Resource \FileReference ;
@@ -33,6 +34,10 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
33
34
ConstructibleFromArray::class,
34
35
'fromArray '
35
36
],
37
+ 'NULL ' => [
38
+ ConstructibleFromNull::class,
39
+ 'fromNull '
40
+ ],
36
41
FileReference::class => [
37
42
ConstructibleFromFileInterface::class,
38
43
'fromFileInterface '
@@ -55,6 +60,13 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
55
60
],
56
61
];
57
62
63
+ /**
64
+ * Runtime cache to speed up conversion checks
65
+ *
66
+ * @var array
67
+ */
68
+ protected $ conversionCache = [];
69
+
58
70
/**
59
71
* Adds an interface to specify argument type conversion to list
60
72
*
@@ -91,22 +103,32 @@ public function removeConversionInterface(string $fromType): self
91
103
*/
92
104
public function canTypeBeConvertedToType (string $ givenType , string $ toType ): bool
93
105
{
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 ) {
96
108
return false ;
97
109
}
98
110
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
99
117
// 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
+ );
102
126
}
103
127
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 ;
110
132
}
111
133
112
134
/**
0 commit comments