Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feature/reintroduce…
Browse files Browse the repository at this point in the history
…HiddenOrDisabledNodes
  • Loading branch information
mhsdesign committed Jun 7, 2023
2 parents b99832e + a3684ba commit 0f95072
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 24 deletions.
3 changes: 2 additions & 1 deletion Classes/Domain/ExceptionHandling/ExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ class ExceptionHandler
protected $throwableStorage;

/**
* @var ExceptionHandlingConfiguration
* @Flow\Inject
*/
protected ExceptionHandlingConfiguration $configuration;
protected $configuration;

public function handleAfterTemplateConfigurationProcessing(CaughtExceptions $caughtExceptions, NodeInterface $node): void
{
Expand Down
9 changes: 4 additions & 5 deletions Classes/Domain/NodeCreation/PropertiesAndReferences.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ public static function createFromArrayAndTypeDeclarations(array $propertiesAndRe
public function requireValidProperties(NodeType $nodeType, CaughtExceptions $caughtExceptions): array
{
$validProperties = [];
$defaultValues = $nodeType->getDefaultValuesForProperties();
foreach ($this->properties as $propertyName => $propertyValue) {
$this->assertValidPropertyName($propertyName);
try {
$this->assertValidPropertyName($propertyName);
if (!isset($nodeType->getProperties()[$propertyName])) {
throw new PropertyIgnoredException(
sprintf(
Expand Down Expand Up @@ -109,14 +108,14 @@ public function requireValidReferences(NodeType $nodeType, Context $subgraph, Ca

/**
* In the old CR, it was common practice to set internal or meta properties via this syntax: `_hidden` but we don't allow this anymore.
* @throws \InvalidArgumentException
* @throws PropertyIgnoredException
*/
private function assertValidPropertyName($propertyName): void
{
$legacyInternalProperties = ['_accessRoles', '_contentObject', '_hidden', '_hiddenAfterDateTime', '_hiddenBeforeDateTime', '_hiddenInIndex',
'_index', '_name', '_nodeType', '_removed', '_workspace'];
if (!is_string($propertyName) || $propertyName === '') {
throw new \InvalidArgumentException(sprintf('Property name must be a non empty string. Got "%s".', $propertyName));
throw new PropertyIgnoredException(sprintf('Because property name must be a non empty string. Got "%s".', $propertyName), 1686149518395);
}
if ($propertyName[0] === '_') {
$lowerPropertyName = strtolower($propertyName);
Expand All @@ -125,7 +124,7 @@ private function assertValidPropertyName($propertyName): void
}
foreach ($legacyInternalProperties as $legacyInternalProperty) {
if ($lowerPropertyName === strtolower($legacyInternalProperty)) {
throw new \InvalidArgumentException(sprintf('Internal legacy property "%s" not implement.', $propertyName));
throw new PropertyIgnoredException(sprintf('Because internal legacy property "%s" not implement.', $propertyName), 1686149513158);
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions Classes/Domain/Template/RootTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

namespace Flowpack\NodeTemplates\Domain\Template;

use Flowpack\NodeTemplates\Domain\Template\Template;
use Flowpack\NodeTemplates\Domain\Template\Templates;
use Neos\Flow\Annotations as Flow;

/**
Expand Down Expand Up @@ -34,6 +32,11 @@ public function __construct(?bool $disabled, array $properties, Templates $child
$this->childNodes = $childNodes;
}

public static function empty(): self
{
return new RootTemplate(null, [], Templates::empty());
}

public function getDisabled(): ?bool
{
return $this->disabled;
Expand Down
3 changes: 1 addition & 2 deletions Classes/Domain/Template/Template.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

namespace Flowpack\NodeTemplates\Domain\Template;

use Flowpack\NodeTemplates\Domain\Template\Templates;
use Neos\ContentRepository\Domain\NodeType\NodeTypeName;
use Neos\ContentRepository\Domain\NodeAggregate\NodeName;
use Neos\ContentRepository\Domain\NodeType\NodeTypeName;
use Neos\Flow\Annotations as Flow;

/** @Flow\Proxy(false) */
Expand Down
4 changes: 1 addition & 3 deletions Classes/Domain/Template/Templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Flowpack\NodeTemplates\Domain\Template;

use Flowpack\NodeTemplates\Domain\Template\RootTemplate;
use Flowpack\NodeTemplates\Domain\Template\Template;
use Neos\Flow\Annotations as Flow;

/** @Flow\Proxy(false) */
Expand Down Expand Up @@ -53,7 +51,7 @@ public function toRootTemplate(): RootTemplate
$first->getChildNodes()
);
}
return new RootTemplate(null, [], Templates::empty());
return RootTemplate::empty();
}

public function jsonSerialize()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Flowpack\NodeTemplates\Domain\Template\RootTemplate;
use Flowpack\NodeTemplates\Domain\Template\Template;
use Flowpack\NodeTemplates\Domain\Template\Templates;
use Flowpack\NodeTemplates\Domain\TemplateConfiguration\EelEvaluationService;
use Neos\ContentRepository\Domain\NodeAggregate\NodeName;
use Neos\ContentRepository\Domain\NodeType\NodeTypeName;
use Neos\Flow\Annotations as Flow;
Expand All @@ -31,12 +30,16 @@ class TemplateConfigurationProcessor
*/
public function processTemplateConfiguration(array $configuration, array $evaluationContext, CaughtExceptions $caughtEvaluationExceptions): RootTemplate
{
$templatePart = TemplatePart::createRoot(
$configuration,
$evaluationContext,
fn ($value, $evaluationContext) => $this->preprocessConfigurationValue($value, $evaluationContext),
$caughtEvaluationExceptions
);
try {
$templatePart = TemplatePart::createRoot(
$configuration,
$evaluationContext,
fn ($value, $evaluationContext) => $this->preprocessConfigurationValue($value, $evaluationContext),
$caughtEvaluationExceptions
);
} catch (StopBuildingTemplatePartException $e) {
return RootTemplate::empty();
}
return $this->createTemplatesFromTemplatePart($templatePart)->toRootTemplate();
}

Expand Down Expand Up @@ -91,7 +94,10 @@ private function createTemplateFromTemplatePart(TemplatePart $templatePart): Tem
$processedProperties = [];
foreach ($templatePart->getRawConfiguration('properties') ?? [] as $propertyName => $value) {
if (!is_scalar($value) && !is_null($value)) {
throw new \InvalidArgumentException(sprintf('Template configuration properties can only hold int|float|string|bool|null. Property "%s" has type "%s"', $propertyName, gettype($value)), 1685725310730);
$templatePart->getCaughtExceptions()->add(CaughtException::fromException(
new \RuntimeException(sprintf('Template configuration properties can only hold int|float|string|bool|null. Property "%s" has type "%s"', $propertyName, gettype($value)), 1685725310730)
));
continue;
}
try {
$processedProperties[$propertyName] = $templatePart->processConfiguration(['properties', $propertyName]);
Expand All @@ -102,7 +108,11 @@ private function createTemplateFromTemplatePart(TemplatePart $templatePart): Tem
// process the childNodes
$childNodeTemplates = Templates::empty();
foreach ($templatePart->getRawConfiguration('childNodes') ?? [] as $childNodeConfigurationPath => $_) {
$childNodeTemplatePart = $templatePart->withConfigurationByConfigurationPath(['childNodes', $childNodeConfigurationPath]);
try {
$childNodeTemplatePart = $templatePart->withConfigurationByConfigurationPath(['childNodes', $childNodeConfigurationPath]);
} catch (StopBuildingTemplatePartException $e) {
continue;
}
$childNodeTemplates = $childNodeTemplates->merge($this->createTemplatesFromTemplatePart($childNodeTemplatePart));
}

Expand Down
16 changes: 14 additions & 2 deletions Classes/Domain/TemplateConfiguration/TemplatePart.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class TemplatePart
* @psalm-param array<string, mixed> $configuration
* @psalm-param array<string, mixed> $evaluationContext
* @psalm-param \Closure(mixed $value, array<string, mixed> $evaluationContext): mixed $configurationValueProcessor
* @throws StopBuildingTemplatePartException
*/
private function __construct(
array $configuration,
Expand All @@ -63,6 +64,7 @@ private function __construct(
* @psalm-param array<string, mixed> $configuration
* @psalm-param array<string, mixed> $evaluationContext
* @psalm-param \Closure(mixed $value, array<string, mixed> $evaluationContext): mixed $configurationValueProcessor
* @throws StopBuildingTemplatePartException
*/
public static function createRoot(
array $configuration,
Expand Down Expand Up @@ -91,6 +93,7 @@ public function getFullPathToConfiguration(): array

/**
* @psalm-param string|list<string> $configurationPath
* @throws StopBuildingTemplatePartException
*/
public function withConfigurationByConfigurationPath($configurationPath): self
{
Expand Down Expand Up @@ -188,16 +191,25 @@ public function hasConfiguration($configurationPath): bool
return true;
}

/**
* @throws StopBuildingTemplatePartException
*/
private function validateTemplateConfigurationKeys(): void
{
$isRootTemplate = $this->fullPathToConfiguration === [];
foreach (array_keys($this->configuration) as $key) {
if (!in_array($key, ['type', 'name', 'disabled', 'properties', 'childNodes', 'when', 'withItems', 'withContext'], true)) {
throw new \InvalidArgumentException(sprintf('Template configuration has illegal key "%s"', $key));
$this->caughtExceptions->add(
CaughtException::fromException(new \InvalidArgumentException(sprintf('Template configuration has illegal key "%s"', $key), 1686150349274))
);
throw new StopBuildingTemplatePartException();
}
if ($isRootTemplate) {
if (!in_array($key, ['disabled', 'properties', 'childNodes', 'when', 'withContext'], true)) {
throw new \InvalidArgumentException(sprintf('Root template configuration doesnt allow option "%s', $key));
$this->caughtExceptions->add(
CaughtException::fromException(new \InvalidArgumentException(sprintf('Root template configuration doesnt allow option "%s', $key), 1686150340657))
);
throw new StopBuildingTemplatePartException();
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions Configuration/Testing/NodeTypes.Malformed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@
template:
properties:
foo: "${cannotCallThis()}"
# legacy properties fail
_hidden: true
_hiddenAfterDateTime: 123
boolValue: 123
stringValue: false
reference: "non-existing-node-id"
references: "${['non-existing-node-id']}"
working: "working"
nonDeclaredProperty: "hi"
bar: "${'left open"
# only simple scalar types
nonEelArrayNotAllowed:
not: allowed
childNodes:
whenAbort:
type: 'Flowpack.NodeTemplates:Content.Text'
Expand Down Expand Up @@ -85,3 +91,5 @@
typeCantMutate:
name: "type-cant-mutate"
type: "Flowpack.NodeTemplates:Content.WithEvaluationExceptions"
invalidOption:
crazy: me
16 changes: 16 additions & 0 deletions Tests/Functional/Fixtures/WithEvaluationExceptions.messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"message": "Expression \"${'left open\" in \"properties.bar\" | EelException(The EEL expression \"${'left open\" was not a valid EEL expression. Perhaps you forgot to wrap it in ${...}?, 1410441849)",
"severity": "ERROR"
},
{
"message": "RuntimeException(Template configuration properties can only hold int|float|string|bool|null. Property \"nonEelArrayNotAllowed\" has type \"array\", 1685725310730)",
"severity": "ERROR"
},
{
"message": "Expression \"${parse \u00e4\u00fc\u00e4\u00f6 error}\" in \"childNodes.whenAbort.when\" | ParserException(Expression \"parse \u00e4\u00fc\u00e4\u00f6 error\" could not be parsed. Error starting at character 5: \" \u00e4\u00fc\u00e4\u00f6 error\"., 1327682383)",
"severity": "ERROR"
Expand Down Expand Up @@ -43,6 +47,18 @@
"message": "Configuration \"null\" in \"childNodes.withItemsAbortBecauseNotIterable.withItems\" | RuntimeException(Type NULL is not iterable., 1685802354186)",
"severity": "ERROR"
},
{
"message": "InvalidArgumentException(Template configuration has illegal key \"crazy\", 1686150349274)",
"severity": "ERROR"
},
{
"message": "Property \"_hidden\" in NodeType \"Flowpack.NodeTemplates:Content.WithEvaluationExceptions\" | PropertyIgnoredException(Because internal legacy property \"_hidden\" not implement., 1686149513158)",
"severity": "ERROR"
},
{
"message": "Property \"_hiddenAfterDateTime\" in NodeType \"Flowpack.NodeTemplates:Content.WithEvaluationExceptions\" | PropertyIgnoredException(Because internal legacy property \"_hiddenAfterDateTime\" not implement., 1686149513158)",
"severity": "ERROR"
},
{
"message": "Property \"boolValue\" in NodeType \"Flowpack.NodeTemplates:Content.WithEvaluationExceptions\" | PropertyIgnoredException(Because value `123` is not assignable to property type \"boolean\"., 1685958105644)",
"severity": "ERROR"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"disabled": null,
"properties": {
"_hidden": true,
"_hiddenAfterDateTime": 123,
"boolValue": 123,
"stringValue": false,
"reference": "non-existing-node-id",
Expand Down

0 comments on commit 0f95072

Please sign in to comment.