Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ indent_size = 4

[*.ts]
indent_size = 4

[*.json]
indent_size = 2
23 changes: 3 additions & 20 deletions Classes/Aspect/DebugAttributeAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Neos\Flow\Aop\JoinPointInterface;
use Neos\Fusion\Core\Runtime;
use Neos\Fusion\Core\RuntimeConfiguration;
use Neos\Fusion\Exception as FusionException;

#[Flow\Scope("singleton")]
#[Flow\Aspect]
Expand All @@ -34,9 +35,7 @@ class DebugAttributeAspect
/**
* Lazily built reflection for the protected RuntimeContentCache::$runtime property.
* ReflectionProperty instances are immutable for our read use and can be reused
* across any instance of the (proxy) class - building one ReflectionProperty per
* call (as ObjectAccess::getProperty(..., true) does internally) is the dominant
* cost when this advice fires thousands of times per render.
* across any instance of the (proxy) class.
*/
private ?\ReflectionProperty $runtimePropertyReflection = null;

Expand Down Expand Up @@ -107,14 +106,8 @@ public function onLeave(JoinPointInterface $joinPoint): void
* Resolve the cached Runtime + RuntimeConfiguration for the given proxy and
* return the Fusion configuration for $fusionPath.
*
* Resolution is amortised across calls: the first time we see a proxy instance
* we reach into the (protected) properties once via ReflectionProperty, then
* store references keyed by the proxy. Subsequent calls reuse those references
* and bypass ObjectAccess::getProperty() entirely, which would otherwise build
* a fresh ReflectionProperty + setAccessible(true) for every single enter()
* advice invocation - the dominant cost of this aspect during rendering.
*
* @return array<string, mixed>
* @throws FusionException
*/
private function getFusionConfiguration(object $runtimeContentCache, string $fusionPath): array
{
Expand All @@ -139,12 +132,6 @@ private function getFusionConfiguration(object $runtimeContentCache, string $fus
return $runtimeConfiguration->forPath($fusionPath);
}

/**
* Read the protected RuntimeContentCache::$runtime property using a cached
* ReflectionProperty. The property declaration lives on the original class
* (Flow proxy subclasses inherit it), so a single ReflectionProperty is
* valid for any instance - including proxies built by Flow's AOP.
*/
private function readRuntimeProperty(object $runtimeContentCache): ?Runtime
{
if ($this->runtimePropertyReflection === null) {
Expand All @@ -163,10 +150,6 @@ private function readRuntimeProperty(object $runtimeContentCache): ?Runtime
return $value instanceof Runtime ? $value : null;
}

/**
* Read the protected Runtime::$runtimeConfiguration property using a cached
* ReflectionProperty, analogous to readRuntimeProperty().
*/
private function readRuntimeConfigurationProperty(Runtime $runtime): ?RuntimeConfiguration
{
if ($this->runtimeConfigurationPropertyReflection === null) {
Expand Down
19 changes: 19 additions & 0 deletions Classes/Interface/DummySearchInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Flowpack\Neos\Debug\Interface;

/**
* Define dummy interface for the `SearchQueryAspect` if the Neos.ContentRepository.Search package hasn't been installed.
*/
interface DummySearchInterface
{
}

if (!interface_exists('Neos\ContentRepository\Search\Search\QueryBuilderInterface', false)) {
class_alias(
DummySearchInterface::class,
'Neos\ContentRepository\Search\Search\QueryBuilderInterface'
);
}
Loading