-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
!!! FEATURE: NodeTemplates Version 2.0 #53
!!! FEATURE: NodeTemplates Version 2.0
- Loading branch information
Showing
58 changed files
with
3,199 additions
and
700 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
Classes/Domain/DelegatingDocumentTitleNodeCreationHandler.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Flowpack\NodeTemplates\Domain; | ||
|
||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
use Neos\Flow\Annotations as Flow; | ||
use Neos\Neos\Ui\NodeCreationHandler\DocumentTitleNodeCreationHandler; | ||
use Neos\Neos\Ui\NodeCreationHandler\NodeCreationHandlerInterface; | ||
|
||
/** | ||
* Augments the original neos ui document title node creation handler, which takes care of setting the "uriPathSegment" based of the title. | ||
* This handler steps in when a node has a node template with the property `uriPathSegment`. | ||
* In this case we will prevent the original handler from being called, as we handle setting the `uriPathSegment` ourselves and the original handler will just override our `uriPathSegment` again. | ||
* | ||
* @todo once we have sorting with https://github.com/neos/neos-ui/pull/3511 we can put our handler at the end instead. | ||
*/ | ||
class DelegatingDocumentTitleNodeCreationHandler implements NodeCreationHandlerInterface | ||
{ | ||
/** | ||
* @Flow\Inject | ||
* @var DocumentTitleNodeCreationHandler | ||
*/ | ||
protected $originalDocumentTitleNodeCreationHandler; | ||
|
||
/** | ||
* @throws \Neos\Eel\Exception | ||
* @throws \Neos\Neos\Exception | ||
*/ | ||
public function handle(NodeInterface $node, array $data): void | ||
{ | ||
$template = $node->getNodeType()->getOptions()['template'] ?? null; | ||
if ( | ||
!$template | ||
|| !isset($template['properties']['uriPathSegment']) | ||
) { | ||
$this->originalDocumentTitleNodeCreationHandler->handle($node, $data); | ||
return; | ||
} | ||
|
||
// do nothing, as we handle this already when applying the template | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
|
||
use Neos\Flow\Annotations as Flow; | ||
|
||
/** | ||
* @Flow\Proxy(false) | ||
*/ | ||
class CaughtException | ||
{ | ||
private \Throwable $exception; | ||
|
||
private ?string $origin; | ||
|
||
private function __construct(\Throwable $exception, ?string $origin) | ||
{ | ||
$this->exception = $exception; | ||
$this->origin = $origin; | ||
} | ||
|
||
public static function fromException(\Throwable $exception): self | ||
{ | ||
return new self($exception, null); | ||
} | ||
|
||
public function withOrigin(string $origin): self | ||
{ | ||
return new self($this->exception, $origin); | ||
} | ||
|
||
public function getException(): \Throwable | ||
{ | ||
return $this->exception; | ||
} | ||
|
||
public function getOrigin(): ?string | ||
{ | ||
return $this->origin; | ||
} | ||
|
||
public function toMessage(): string | ||
{ | ||
$messageLines = []; | ||
|
||
if ($this->origin) { | ||
$messageLines[] = $this->origin; | ||
} | ||
|
||
$level = 0; | ||
$exception = $this->exception; | ||
do { | ||
$level++; | ||
if ($level >= 8) { | ||
$messageLines[] = '...Recursion'; | ||
break; | ||
} | ||
|
||
$reflexception = new \ReflectionClass($exception); | ||
$shortExceptionName = $reflexception->getShortName(); | ||
if ($shortExceptionName === 'Exception') { | ||
$secondPartOfPackageName = explode('\\', $reflexception->getNamespaceName())[1] ?? ''; | ||
$shortExceptionName = $secondPartOfPackageName . $shortExceptionName; | ||
} | ||
$messageLines[] = sprintf('%s(%s, %s)', $shortExceptionName, $exception->getMessage(), $exception->getCode()); | ||
} while ($exception = $exception->getPrevious()); | ||
|
||
return join(' | ', $messageLines); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
use Flowpack\NodeTemplates\Domain\ExceptionHandling\CaughtException; | ||
use Neos\Flow\Annotations as Flow; | ||
|
||
/** @Flow\Proxy(false) */ | ||
class CaughtExceptions implements \IteratorAggregate | ||
{ | ||
/** @var array<int, CaughtException> */ | ||
private array $exceptions = []; | ||
|
||
private function __construct() | ||
{ | ||
} | ||
|
||
public static function create(): self | ||
{ | ||
return new self(); | ||
} | ||
|
||
public function hasExceptions(): bool | ||
{ | ||
return $this->exceptions !== []; | ||
} | ||
|
||
public function add(CaughtException $exception): void | ||
{ | ||
$this->exceptions[] = $exception; | ||
} | ||
|
||
public function first(): ?CaughtException | ||
{ | ||
return $this->exceptions[0] ?? null; | ||
} | ||
|
||
/** | ||
* @return \Traversable<int, CaughtException>|CaughtException[] | ||
*/ | ||
public function getIterator() | ||
{ | ||
yield from $this->exceptions; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
use Neos\Flow\Annotations as Flow; | ||
use Neos\Flow\Log\ThrowableStorageInterface; | ||
use Neos\Flow\Log\Utility\LogEnvironment; | ||
use Neos\Neos\Ui\Domain\Model\Feedback\Messages\Error; | ||
use Neos\Neos\Ui\Domain\Model\FeedbackCollection; | ||
use Psr\Log\LoggerInterface; | ||
|
||
class ExceptionHandler | ||
{ | ||
/** | ||
* @var FeedbackCollection | ||
* @Flow\Inject(lazy=false) | ||
*/ | ||
protected $feedbackCollection; | ||
|
||
/** | ||
* @var LoggerInterface | ||
* @Flow\Inject | ||
*/ | ||
protected $logger; | ||
|
||
/** | ||
* @var ThrowableStorageInterface | ||
* @Flow\Inject | ||
*/ | ||
protected $throwableStorage; | ||
|
||
/** | ||
* @var ExceptionHandlingConfiguration | ||
* @Flow\Inject | ||
*/ | ||
protected $configuration; | ||
|
||
public function handleAfterTemplateConfigurationProcessing(CaughtExceptions $caughtExceptions, NodeInterface $node): void | ||
{ | ||
if (!$caughtExceptions->hasExceptions()) { | ||
return; | ||
} | ||
|
||
if (!$this->configuration->shouldStopOnExceptionAfterTemplateConfigurationProcessing()) { | ||
return; | ||
} | ||
|
||
$templateNotCreatedException = new TemplateNotCreatedException( | ||
sprintf('Template for "%s" was not applied. Only %s was created.', $node->getNodeType()->getLabel(), (string)$node), | ||
1686135532992, | ||
$caughtExceptions->first()->getException(), | ||
); | ||
|
||
$this->logCaughtExceptions($caughtExceptions, $templateNotCreatedException); | ||
|
||
throw $templateNotCreatedException; | ||
} | ||
|
||
public function handleAfterNodeCreation(CaughtExceptions $caughtExceptions, NodeInterface $node): void | ||
{ | ||
if (!$caughtExceptions->hasExceptions()) { | ||
return; | ||
} | ||
|
||
$templatePartiallyCreatedException = new TemplatePartiallyCreatedException( | ||
sprintf('Template for "%s" only partially applied. Please check the newly created nodes beneath %s.', $node->getNodeType()->getLabel(), (string)$node), | ||
1686135564160, | ||
$caughtExceptions->first()->getException(), | ||
); | ||
|
||
$this->logCaughtExceptions($caughtExceptions, $templatePartiallyCreatedException); | ||
|
||
throw $templatePartiallyCreatedException; | ||
} | ||
|
||
/** | ||
* @param TemplateNotCreatedException|TemplatePartiallyCreatedException $templateCreationException | ||
*/ | ||
private function logCaughtExceptions(CaughtExceptions $caughtExceptions, \DomainException $templateCreationException): void | ||
{ | ||
$messages = []; | ||
foreach ($caughtExceptions as $index => $caughtException) { | ||
$messages[sprintf('CaughtException (%s)', $index)] = $caughtException->toMessage(); | ||
} | ||
|
||
// log exception | ||
$messageWithReference = $this->throwableStorage->logThrowable($templateCreationException, $messages); | ||
$this->logger->warning($messageWithReference, LogEnvironment::fromMethodName(__METHOD__)); | ||
|
||
// neos ui logging | ||
$nodeTemplateError = new Error(); | ||
$nodeTemplateError->setMessage($templateCreationException->getMessage()); | ||
|
||
$this->feedbackCollection->add( | ||
$nodeTemplateError | ||
); | ||
|
||
foreach ($messages as $message) { | ||
$error = new Error(); | ||
$error->setMessage($message); | ||
$this->feedbackCollection->add( | ||
$error | ||
); | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
Classes/Domain/ExceptionHandling/ExceptionHandlingConfiguration.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
use Neos\Flow\Annotations as Flow; | ||
|
||
class ExceptionHandlingConfiguration | ||
{ | ||
/** | ||
* @Flow\InjectConfiguration(package="Flowpack.NodeTemplates", path="exceptionHandling") | ||
*/ | ||
protected array $exceptionHandlingConfiguration; | ||
|
||
public function shouldStopOnExceptionAfterTemplateConfigurationProcessing(): bool | ||
{ | ||
return $this->exceptionHandlingConfiguration['templateConfigurationProcessing']['stopOnException'] ?? false; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
Classes/Domain/ExceptionHandling/TemplateNotCreatedException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
/** | ||
* Thrown if the templateConfigurationProcessing was unsuccessful (due to an invalid EEL expression f.x), | ||
* and the {@see ExceptionHandlingConfiguration} is configured not to continue | ||
*/ | ||
class TemplateNotCreatedException extends \DomainException | ||
{ | ||
} |
12 changes: 12 additions & 0 deletions
12
Classes/Domain/ExceptionHandling/TemplatePartiallyCreatedException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
namespace Flowpack\NodeTemplates\Domain\ExceptionHandling; | ||
|
||
/** | ||
* Thrown in the following cases: | ||
* - the templateConfigurationProcessing was unsuccessful (due to an invalid EEL expression f.x) | ||
* - the nodeCreation was unsuccessful (f.x. due to constrains from the cr) | ||
*/ | ||
class TemplatePartiallyCreatedException extends \DomainException | ||
{ | ||
} |
Oops, something went wrong.