diff --git a/CHANGELOG.md b/CHANGELOG.md index 482707cb..a44b30ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +- Avoid error when SchemaManager is called via view helpers in backend context (#108) + ## [2.7.0] - 2023-02-14 ### Added diff --git a/Classes/Adapter/ApplicationType.php b/Classes/Adapter/ApplicationType.php index 9589ea7e..97778acc 100644 --- a/Classes/Adapter/ApplicationType.php +++ b/Classes/Adapter/ApplicationType.php @@ -12,6 +12,7 @@ namespace Brotkrueml\Schema\Adapter; use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Http\ApplicationType as CoreApplicationType; /** @@ -23,6 +24,11 @@ class ApplicationType public function isBackend(): bool { + if (Environment::isCli()) { + // This is helpful in functional tests + return false; + } + if ($this->applicationType === null) { $this->applicationType = CoreApplicationType::fromRequest($this->getRequest()); } diff --git a/Classes/Manager/SchemaManager.php b/Classes/Manager/SchemaManager.php index 7b3bc747..ccdd039b 100644 --- a/Classes/Manager/SchemaManager.php +++ b/Classes/Manager/SchemaManager.php @@ -11,6 +11,7 @@ namespace Brotkrueml\Schema\Manager; +use Brotkrueml\Schema\Adapter\ApplicationType; use Brotkrueml\Schema\Core\Model\TypeInterface; use Brotkrueml\Schema\Core\Model\WebPageTypeInterface; use Brotkrueml\Schema\Event\InitialiseTypesEvent; @@ -44,15 +45,22 @@ final class SchemaManager implements SingletonInterface private array $breadcrumbLists = []; private MainEntityOfWebPageBag $mainEntityOfWebPageBag; + private ApplicationType $applicationType; public function __construct( + ?ApplicationType $applicationType = null, ?EventDispatcherInterface $eventDispatcher = null, ?ExtensionConfiguration $extensionConfiguration = null, ?RendererInterface $renderer = null ) { - $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class); + $this->applicationType = $applicationType ?? new ApplicationType(); $this->renderer = $renderer ?? new Renderer(); $this->mainEntityOfWebPageBag = new MainEntityOfWebPageBag(); + $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class); + + if ($this->applicationType->isBackend()) { + return; + } $eventDispatcher ??= GeneralUtility::makeInstance(EventDispatcherInterface::class); /** @var InitialiseTypesEvent $event */ diff --git a/Documentation/Changelog/Index.rst b/Documentation/Changelog/Index.rst index def08442..dbd91cbc 100644 --- a/Documentation/Changelog/Index.rst +++ b/Documentation/Changelog/Index.rst @@ -11,6 +11,12 @@ to `Semantic Versioning `_. `Unreleased `_ ------------------------------------------------------------------------------ +Fixed +^^^^^ + + +* Avoid error when SchemaManager is called via view helpers in backend context (#108) + `2.7.0 `_ - 2023-02-14 ---------------------------------------------------------------------------------------- diff --git a/Tests/Unit/Hooks/PageRenderer/SchemaMarkupInjectionTest.php b/Tests/Unit/Hooks/PageRenderer/SchemaMarkupInjectionTest.php index 01df40a0..3edf7f34 100644 --- a/Tests/Unit/Hooks/PageRenderer/SchemaMarkupInjectionTest.php +++ b/Tests/Unit/Hooks/PageRenderer/SchemaMarkupInjectionTest.php @@ -74,6 +74,11 @@ final class SchemaMarkupInjectionTest extends TestCase protected function setUp(): void { + $applicationTypeStub = $this->createStub(ApplicationType::class); + $applicationTypeStub + ->method('isBackend') + ->willReturn(false); + $this->controllerMock = $this->createMock(TypoScriptFrontendController::class); $this->controllerMock->newHash = 'somehash'; $this->controllerMock->page = [ @@ -83,6 +88,7 @@ protected function setUp(): void $this->extensionConfigurationMock = $this->createMock(ExtensionConfiguration::class); $this->schemaManager = new SchemaManager( + $applicationTypeStub, new NoopEventDispatcher(), $this->extensionConfigurationMock, new Renderer() diff --git a/Tests/Unit/Manager/SchemaManagerTest.php b/Tests/Unit/Manager/SchemaManagerTest.php index e81af13d..e1d894b6 100644 --- a/Tests/Unit/Manager/SchemaManagerTest.php +++ b/Tests/Unit/Manager/SchemaManagerTest.php @@ -11,6 +11,7 @@ namespace Brotkrueml\Schema\Tests\Unit\Manager; +use Brotkrueml\Schema\Adapter\ApplicationType; use Brotkrueml\Schema\Core\Model\TypeInterface; use Brotkrueml\Schema\JsonLd\Renderer; use Brotkrueml\Schema\Manager\SchemaManager; @@ -23,6 +24,7 @@ use Brotkrueml\Schema\Tests\Fixtures\Model\ServiceStub; use Brotkrueml\Schema\Tests\Helper\NoopEventDispatcher; use Brotkrueml\Schema\Tests\Helper\SchemaCacheTrait; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Core\Configuration\ExtensionConfiguration; @@ -35,6 +37,10 @@ final class SchemaManagerTest extends Testcase private SchemaManager $subject; private \ReflectionProperty $rendererTypes; private Renderer $renderer; + /** + * @var ApplicationType&Stub + */ + private Stub $applicationTypeStub; protected function setUp(): void { @@ -44,8 +50,14 @@ protected function setUp(): void $this->rendererTypes = $reflector->getProperty('types'); $this->rendererTypes->setAccessible(true); + $this->applicationTypeStub = $this->createStub(ApplicationType::class); + $this->applicationTypeStub + ->method('isBackend') + ->willReturn(false); + $this->renderer = new Renderer(); $this->subject = new SchemaManager( + $this->applicationTypeStub, new NoopEventDispatcher(), $this->createStub(ExtensionConfiguration::class), $this->renderer @@ -358,6 +370,7 @@ public function dispatch(object $event) }; $subject = new SchemaManager( + $this->applicationTypeStub, $eventDispatcherStub, $this->createStub(ExtensionConfiguration::class), $this->renderer @@ -384,6 +397,7 @@ public function onlyOneBreadCrumbListIsRenderedIfExtensionConfigurationIsEnabled ->willReturn('1'); $subject = new SchemaManager( + $this->applicationTypeStub, new NoopEventDispatcher(), $extensionConfigurationStub, $this->renderer @@ -415,6 +429,7 @@ public function allBreadCrumbListsAreRenderedIfExtensionConfigurationIsDisabled( ->willReturn('0'); $subject = new SchemaManager( + $this->applicationTypeStub, new NoopEventDispatcher(), $extensionConfigurationStub, $this->renderer @@ -464,4 +479,31 @@ public function multipleCallsOfRenderJsonLd(): void $this->subject->renderJsonLd(); self::assertCount(1, $this->rendererTypes->getValue($this->renderer)); } + + /** + * @test + */ + public function inBackendContextTheEventDispatcherIsNotCalled(): void + { + self::expectNotToPerformAssertions(); + + $applicationTypeStub = $this->createStub(ApplicationType::class); + $applicationTypeStub + ->method('isBackend') + ->willReturn(true); + + $eventDispatcherStub = new class() implements EventDispatcherInterface { + public function dispatch(object $event) + { + throw new \Exception('dispatch() method must not be called'); + } + }; + + new SchemaManager( + $applicationTypeStub, + $eventDispatcherStub, + $this->createStub(ExtensionConfiguration::class), + $this->renderer + ); + } } diff --git a/phpstan.baseline.neon b/phpstan.baseline.neon index 182ea9eb..8dde31ed 100644 --- a/phpstan.baseline.neon +++ b/phpstan.baseline.neon @@ -111,7 +111,7 @@ parameters: path: Classes/Manager/SchemaManager.php - - message: "#^Class cognitive complexity is 25, keep it under 20$#" + message: "#^Class cognitive complexity is 26, keep it under 20$#" count: 1 path: Classes/Manager/SchemaManager.php