Skip to content

Commit

Permalink
Merge pull request #54 from sitegeist/feature/componentAwareDataStruc…
Browse files Browse the repository at this point in the history
…tures

Feature/component aware data structures
  • Loading branch information
s2b authored Jul 1, 2020
2 parents 00a185f + 849be1f commit 210dbac
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 11 deletions.
7 changes: 7 additions & 0 deletions Classes/Fluid/ViewHelper/ComponentRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SMS\FluidComponents\Fluid\ViewHelper;

use SMS\FluidComponents\Interfaces\ComponentAware;
use SMS\FluidComponents\Utility\ComponentArgumentConverter;
use SMS\FluidComponents\Utility\ComponentLoader;
use SMS\FluidComponents\Utility\ComponentPrefixer\ComponentPrefixerInterface;
Expand Down Expand Up @@ -148,6 +149,12 @@ public function render()
$argumentType = $this->argumentDefinitions[$name]->getType();

$argument = $componentArgumentConverter->convertValueToType($argument, $argumentType);

// Provide component namespace to certain data structures
if ($argument instanceof ComponentAware) {
$argument->setComponentNamespace($this->componentNamespace);
}

$variableContainer->add($name, $argument);
}

Expand Down
15 changes: 15 additions & 0 deletions Classes/Interfaces/ComponentAware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace SMS\FluidComponents\Interfaces;

/**
* By implementing ComponentAware in a data structure, fluid
* components will provide the component namespace to the data
* structure when used in a component call so that the data structure
* can behave differently for each component (e. g. by reading
* something from the component's directory)
*/
interface ComponentAware
{
public function setComponentNamespace(string $componentNamespace): void;
}
17 changes: 17 additions & 0 deletions Classes/Interfaces/ConstructibleFromNull.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SMS\FluidComponents\Interfaces;

/**
* ConstructibleFromNull defines an alternative constructor
* which initializes the object without any input
*/
interface ConstructibleFromNull
{
/**
* Creates an instance of the class
*
* @return object
*/
public static function fromNull();
}
42 changes: 32 additions & 10 deletions Classes/Utility/ComponentArgumentConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use SMS\FluidComponents\Interfaces\ConstructibleFromExtbaseFile;
use SMS\FluidComponents\Interfaces\ConstructibleFromFileInterface;
use SMS\FluidComponents\Interfaces\ConstructibleFromInteger;
use SMS\FluidComponents\Interfaces\ConstructibleFromNull;
use SMS\FluidComponents\Interfaces\ConstructibleFromString;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\FileReference;
Expand Down Expand Up @@ -33,6 +34,10 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
ConstructibleFromArray::class,
'fromArray'
],
'NULL' => [
ConstructibleFromNull::class,
'fromNull'
],
FileReference::class => [
ConstructibleFromFileInterface::class,
'fromFileInterface'
Expand All @@ -55,6 +60,13 @@ class ComponentArgumentConverter implements \TYPO3\CMS\Core\SingletonInterface
],
];

/**
* Runtime cache to speed up conversion checks
*
* @var array
*/
protected $conversionCache = [];

/**
* Adds an interface to specify argument type conversion to list
*
Expand Down Expand Up @@ -91,22 +103,32 @@ public function removeConversionInterface(string $fromType): self
*/
public function canTypeBeConvertedToType(string $givenType, string $toType): bool
{
// Check if a constructor interface exists for the given type
if (!isset($this->conversionInterfaces[$givenType])) {
// No need to convert equal types
if ($givenType === $toType) {
return false;
}

// Has this check already been computed?
if (isset($this->conversionCache[$givenType . '|' . $toType])) {
return $this->conversionCache[$givenType . '|' . $toType];
}

// Check if a constructor interface exists for the given type
// Check if the target type is a PHP class
if (!class_exists($toType)) {
return false;
$canBeConverted = false;
if (isset($this->conversionInterfaces[$givenType]) && class_exists($toType)) {
// Check if the target type implements the constructor interface
// required for conversion
$canBeConverted = is_subclass_of(
$toType,
$this->conversionInterfaces[$givenType][0]
);
}

// Check if the target type implements the constructor interface
// required for conversion
return is_subclass_of(
$toType,
$this->conversionInterfaces[$givenType][0]
);
// Add to runtime cache
$this->conversionCache[$givenType . '|' . $toType] = $canBeConverted;

return $canBeConverted;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ext_emconf.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
'state' => 'stable',
'uploadfolder' => false,
'clearCacheOnLoad' => false,
'version' => '2.0.1',
'version' => '2.1.0',
'constraints' => [
'depends' => [
'typo3' => '9.5.0-10.9.99',
Expand Down

0 comments on commit 210dbac

Please sign in to comment.