Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Improve context rewrites in fusion #122

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
41 changes: 38 additions & 3 deletions config/set/contentrepository-90.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Neos\Rector\ContentRepository90\Rules\FusionCachingNodeInEntryIdentifierRector;
use Neos\Rector\ContentRepository90\Rules\FusionContextCurrentRenderingModeRector;
use Neos\Rector\ContentRepository90\Rules\FusionContextCurrentSiteRector;
use Neos\Rector\ContentRepository90\Rules\FusionContextGetWorkspaceNameRector;
use Neos\Rector\ContentRepository90\Rules\FusionContextInBackendRector;
use Neos\Rector\ContentRepository90\Rules\FusionContextLiveRector;
use Neos\Rector\ContentRepository90\Rules\FusionNodeAggregateIdentifierRector;
Expand Down Expand Up @@ -366,10 +367,10 @@
$rectorConfig->rule(ContextFactoryToLegacyContextStubRector::class);
// Context::getWorkspaceName()
// TODO: PHP
// TODO: Fusion
$rectorConfig->rule(FusionContextGetWorkspaceNameRector::class);
// Context::getRootNode()
$rectorConfig->rule(ContextGetRootNodeRector::class);
// TODO: Fusion
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.rootNode', 'Line %LINE: !! node.context.rootNode is removed in Neos 9.0.');
// Context::getNode()
// TODO: PHP
// Context::getNodeByIdentifier()
Expand All @@ -379,9 +380,43 @@
// Context::getNodesOnPath()
// TODO: PHP
// Context::adoptNode()
// TODO: PHP
// Context::getFirstLevelNodeCache()
$rectorConfig->rule(ContextGetFirstLevelNodeCacheRector::class);
// getCurrentDateTime(): DateTime|DateTimeInterface
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.currentDateTime', 'Line %LINE: !! node.context.currentDateTime is removed in Neos 9.0.');
// getDimensions(): array
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.dimensions', 'Line %LINE: !! node.context.dimensions is removed in Neos 9.0. You can get node DimensionSpacePoints via node.dimensionSpacePoints now.');
// getNodeByIdentifier(identifier: string): NodeInterface|null
// TODO: PHP
// getProperties(): array
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.properties', 'Line %LINE: !! node.context.properties is removed in Neos 9.0.');
// getTargetDimensions(): array
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.targetDimensions', 'Line %LINE: !! node.context.targetDimensions is removed in Neos 9.0.');
// getTargetDimensionValues(): array
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.targetDimensionValues', 'Line %LINE: !! node.context.targetDimensionValues is removed in Neos 9.0.');
// getWorkspace([createWorkspaceIfNecessary: bool = true]): Workspace
// TODO: PHP
// TODO: Fusion?
// isInaccessibleContentShown(): bool
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.isInaccessibleContentShown', 'Line %LINE: !! node.context.isInaccessibleContentShown is removed in Neos 9.0.');
// isInvisibleContentShown(): bool
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.isInvisibleContentShown', 'Line %LINE: !! node.context.isInvisibleContentShown is removed in Neos 9.0.');
// isRemovedContentShown(): bool
// TODO: PHP
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.isRemovedContentShown', 'Line %LINE: !! node.context.isRemovedContentShown is removed in Neos 9.0.');
// validateWorkspace(workspace: Workspace): void
// TODO: PHP



/**
* ContentContext
*/
Expand All @@ -393,7 +428,7 @@
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.currentDomain', 'Line %LINE: !! node.context.currentDomain is removed in Neos 9.0.');
// ContentContext::getCurrentSiteNode
$methodCallToWarningComments[] = new MethodCallToWarningComment(LegacyContextStub::class, 'getCurrentSiteNode', '!! ContentContext::getCurrentSiteNode() is removed in Neos 9.0. Use Subgraph and traverse up to "Neos.Neos:Site" node.');
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.currentSiteNode', 'Line %LINE: !! node.context.currentSiteNode is removed in Neos 9.0.');
$fusionNodePropertyPathToWarningComments[] = new FusionNodePropertyPathToWarningComment('context.currentSiteNode', 'Line %LINE: !! node.context.currentSiteNode is removed in Neos 9.0. Check if you can\'t simply use ${site}.');
// ContentContext::isLive -> renderingMode.isLive
$rectorConfig->rule(ContextIsLiveRector::class);
$rectorConfig->rule(FusionContextLiveRector::class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Neos\Rector\ContentRepository90\Rules;

use Neos\Rector\Core\FusionProcessing\EelExpressionTransformer;
use Neos\Rector\Core\FusionProcessing\FusionRectorInterface;
use Neos\Rector\Utility\CodeSampleLoader;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

class FusionContextGetWorkspaceNameRector implements FusionRectorInterface
{

public function getRuleDefinition(): RuleDefinition
{
return CodeSampleLoader::fromFile('Fusion: Rewrite "node.context.workspaceName" to "node.workspaceName"', __CLASS__);
}

public function refactorFileContent(string $fileContent): string
{
return EelExpressionTransformer::parse($fileContent)
->process(fn(string $eelExpression) => preg_replace(
'/(node|documentNode|site)\.context\.(workspaceName|workspace\.name)\b/',
'$1.workspaceName',
$eelExpression
))
->addCommentsIfRegexMatches(
'/\.context\.workspaceName/',
'// TODO 9.0 migration: Line %LINE: You very likely need to rewrite "VARIABLE.context.workspaceName" to "VARIABLE.workspaceName". We did not auto-apply this migration because we cannot be sure whether the variable is a Node.'
)->getProcessedContent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

workspaceName = ${node.context.workspaceName}
workspaceNameByWorkspace = ${node.context.workspace.name}

attributes = ${node.context.workspaceName || site.context.workspaceName || documentNode.context.workspaceName}


renderer = afx`
<Neos.Context:Component
type="checkbox"
name={node.context.workspaceName}
value={someOtherVariable.context.workspaceName}
/>
`
}
-----
// TODO 9.0 migration: Line 14: You very likely need to rewrite "VARIABLE.context.workspaceName" to "VARIABLE.workspaceName". We did not auto-apply this migration because we cannot be sure whether the variable is a Node.
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

workspaceName = ${node.workspaceName}
workspaceNameByWorkspace = ${node.workspaceName}

attributes = ${node.workspaceName || site.workspaceName || documentNode.workspaceName}


renderer = afx`
<Neos.Context:Component
type="checkbox"
name={node.workspaceName}
value={someOtherVariable.context.workspaceName}
/>
`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Neos\Rector\Tests\ContentRepository90\Rules\FusionContextInBackendRector;

use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class FusionContextGetWorkspaceNameRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $fileInfo): void
{
$this->doTestFile($fileInfo);
}

/**
* @return \Iterator<string>
*/
public function provideData(): \Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture', '*.fusion.inc');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare (strict_types=1);

use Neos\Rector\ContentRepository90\Rules\FusionContextGetWorkspaceNameRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig) : void {
$services = $rectorConfig->services();
$services->defaults()
->public()
->autowire()
->autoconfigure();
$services->set(\Neos\Rector\Core\FusionProcessing\FusionFileProcessor::class);
$rectorConfig->disableParallel(); // does not work for fusion files - see https://github.com/rectorphp/rector-src/pull/2597#issuecomment-1190120688

$rectorConfig->rule(FusionContextGetWorkspaceNameRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

currentSite = ${node.context.currentSite}
currentSiteNode = ${node.context.currentSiteNode}
currentDomain = ${node.context.currentDomain}

isLive = ${node.context.isLive}
isInBackend = ${node.context.isInBackend}

preview = ${node.context.currentRenderingMode.preview}
edit = ${node.context.currentRenderingMode.edit}
name = ${node.context.currentRenderingMode.name}
currentRenderingMode = ${node.context.currentRenderingMode}

properties = ${node.context.properties}

}
-----
// TODO 9.0 migration: Line 19: !! node.context.properties is removed in Neos 9.0.
// TODO 9.0 migration: Line 9: !! node.context.currentDomain is removed in Neos 9.0.
// TODO 9.0 migration: Line 8: !! node.context.currentSiteNode is removed in Neos 9.0. Check if you can't simply use ${site}.
// TODO 9.0 migration: Line 14: You very likely need to rewrite "VARIABLE.context.currentRenderingMode..." to "renderingMode...". We did not auto-apply this migration because we cannot be sure whether the variable is a Node.
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

currentSite = ${Neos.Site.findBySiteNode(site)}
currentSiteNode = ${node.context.currentSiteNode}
currentDomain = ${node.context.currentDomain}

isLive = ${node.context.isLive}
isInBackend = ${node.context.isInBackend}

preview = ${renderingMode.isPreview}
edit = ${renderingMode.isEdit}
name = ${renderingMode.name}
currentRenderingMode = ${node.context.currentRenderingMode}

properties = ${node.context.properties}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
prototype(Neos.Fusion.Form:Checkbox) < prototype(Neos.Fusion.Form:Component.Field) {

renderer = Neos.Fusion:Component {

nodeAttributes = ${node.context.currentRenderingMode.edit || node.context.currentRenderingMode.preview || node.context.currentRenderingMode.title || node.context.currentRenderingMode.name || node.context.currentRenderingMode.fusionPath || node.context.currentRenderingMode.options['foo']}
siteAttributes = ${site.context.currentRenderingMode.edit || site.context.currentRenderingMode.preview || site.context.currentRenderingMode.title || site.context.currentRenderingMode.name || site.context.currentRenderingMode.fusionPath || site.context.currentRenderingMode.options['foo']}
documentNodeAttributes = ${documentNode.context.currentRenderingMode.edit || documentNode.context.currentRenderingMode.preview || documentNode.context.currentRenderingMode.title || documentNode.context.currentRenderingMode.name || documentNode.context.currentRenderingMode.fusionPath || documentNode.context.currentRenderingMode.options['foo']}
other = ${other.context.currentRenderingMode.edit || other.context.currentRenderingMode.preview || other.context.currentRenderingMode.title || other.context.currentRenderingMode.name || other.context.currentRenderingMode.fusionPath || other.context.currentRenderingMode.options['foo']}

renderer = afx`
<input
type="checkbox"
name={node.context.currentRenderingMode.name}
value={node.context.currentRenderingMode.title}
checked={node.context.currentRenderingMode.edit}
{...node.context.currentRenderingMode.options}
/>
`
}
}
-----
// TODO 9.0 migration: Line 9: You very likely need to rewrite "VARIABLE.context.currentRenderingMode..." to "renderingMode...". We did not auto-apply this migration because we cannot be sure whether the variable is a Node.
prototype(Neos.Fusion.Form:Checkbox) < prototype(Neos.Fusion.Form:Component.Field) {

renderer = Neos.Fusion:Component {

nodeAttributes = ${renderingMode.isEdit || renderingMode.isPreview || renderingMode.title || renderingMode.name || renderingMode.fusionPath || renderingMode.options['foo']}
siteAttributes = ${renderingMode.isEdit || renderingMode.isPreview || renderingMode.title || renderingMode.name || renderingMode.fusionPath || renderingMode.options['foo']}
documentNodeAttributes = ${renderingMode.isEdit || renderingMode.isPreview || renderingMode.title || renderingMode.name || renderingMode.fusionPath || renderingMode.options['foo']}
other = ${other.context.currentRenderingMode.edit || other.context.currentRenderingMode.preview || other.context.currentRenderingMode.title || other.context.currentRenderingMode.name || other.context.currentRenderingMode.fusionPath || other.context.currentRenderingMode.options['foo']}

renderer = afx`
<input
type="checkbox"
name={renderingMode.name}
value={renderingMode.title}
checked={renderingMode.isEdit}
{...renderingMode.options}
/>
`
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ prototype(Neos.Fusion.Form:Checkbox) < prototype(Neos.Fusion.Form:Component.Fie
}
}
-----
// TODO 9.0 migration: Line 6: !! node.context.currentSiteNode is removed in Neos 9.0.
// TODO 9.0 migration: Line 6: !! node.context.currentSiteNode is removed in Neos 9.0. Check if you can't simply use ${site}.
prototype(Neos.Fusion.Form:Checkbox) < prototype(Neos.Fusion.Form:Component.Field) {
renderer = Neos.Fusion:Component {
attributes = ${Neos.Site.findBySiteNode(site).siteResourcesPackageKey || Neos.Site.findBySiteNode(site).siteResourcesPackageKey || Neos.Site.findBySiteNode(site).siteResourcesPackageKey}
Expand Down
50 changes: 50 additions & 0 deletions tests/Sets/ContentRepository90/Fixture/Context/context.fusion.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

workspaceName = ${node.context.workspaceName}
workspaceNameByWorkspace = ${node.context.workspace.name}
rootNode = ${node.context.rootNode}

currentDateTime = ${node.context.currentDateTime}
dimensions = ${node.context.dimensions}
properties = ${node.context.properties}

targetDimensions = ${node.context.targetDimensions}
targetDimensionValues = ${node.context.targetDimensionValues}

workspace = ${node.context.workspace}

isInaccessibleContentShown = ${node.context.isInaccessibleContentShown}
isInvisibleContentShown = ${node.context.isInvisibleContentShown}
isRemovedContentShown = ${node.context.isRemovedContentShown}

}
-----
// TODO 9.0 migration: Line 14: !! node.context.rootNode is removed in Neos 9.0.
// TODO 9.0 migration: Line 16: !! node.context.currentDateTime is removed in Neos 9.0.
// TODO 9.0 migration: Line 17: !! node.context.dimensions is removed in Neos 9.0. You can get node DimensionSpacePoints via node.dimensionSpacePoints now.
// TODO 9.0 migration: Line 18: !! node.context.properties is removed in Neos 9.0.
// TODO 9.0 migration: Line 20: !! node.context.targetDimensions is removed in Neos 9.0.
// TODO 9.0 migration: Line 21: !! node.context.targetDimensionValues is removed in Neos 9.0.
// TODO 9.0 migration: Line 25: !! node.context.isInaccessibleContentShown is removed in Neos 9.0.
// TODO 9.0 migration: Line 26: !! node.context.isInvisibleContentShown is removed in Neos 9.0.
// TODO 9.0 migration: Line 27: !! node.context.isRemovedContentShown is removed in Neos 9.0.
prototype(Neos.Context:Prototype) < prototype(Neos.Fusion:Component) {

workspaceName = ${node.workspaceName}
workspaceNameByWorkspace = ${node.workspaceName}
rootNode = ${node.context.rootNode}

currentDateTime = ${node.context.currentDateTime}
dimensions = ${node.context.dimensions}
properties = ${node.context.properties}

targetDimensions = ${node.context.targetDimensions}
targetDimensionValues = ${node.context.targetDimensionValues}

workspace = ${node.context.workspace}

isInaccessibleContentShown = ${node.context.isInaccessibleContentShown}
isInvisibleContentShown = ${node.context.isInvisibleContentShown}
isRemovedContentShown = ${node.context.isRemovedContentShown}

}
Loading