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: Subtree Tags #4659

Merged
merged 59 commits into from
Mar 15, 2024
Merged

!!! FEATURE: Subtree Tags #4659

merged 59 commits into from
Mar 15, 2024

Conversation

bwaidelich
Copy link
Member

@bwaidelich bwaidelich commented Oct 30, 2023

This change introduces the concept of Subtree Tags.

Concept

This change allows arbitrary so called Subtree Tags to be attached to nodes.
They are called Subtree Tags because they are always inherited to all descendant nodes.

That makes it possible to attach recursive information to any node which will be an important requirement for security related features but can also be used for other tasks, e.g. related to rendering.

Constraints and properties

  • If a node is tagged, all descendant nodes will always inherit this tag
  • It's not possible to remove an inherited tag
  • It's possible to tag a node with a value that it already inherits (for example: you can mark a child node of a disabled node explicitly disabled, too. If the parent node is re-enabled, the child node and all descendants still stays disabled)
  • Vice versa it's possible to tag a node with a value some descendant node(s) is/are already tagged with
  • Subtree tag values must be lower case and between 1 and 36 characters long (regex: /^[a-z0-9_.-]{1,36}$/)
  • To the core, Subtree tags have no special meaning. With the exception of the disabled tag that leads to the affected nodes to be excluded from subgraph queries in the frontend
  • The Node read model exposes its tags including the information whether it is an inherited tag

Usage

Add a subtree tag

$contentRepository->handle(TagSubtree::create(
    $contentStreamId,
    $nodeAggregateId,
    $coveredDimensionSpacePoint,
    NodeVariantSelectionStrategy::STRATEGY_ALL_VARIANTS,
    SubtreeTag::fromString('some_tag'),
));

Remove a subtree tag

$contentRepository->handle(UntagSubtree::create(
    $contentStreamId,
    $nodeAggregateId,
    $coveredDimensionSpacePoint,
    NodeVariantSelectionStrategy::STRATEGY_ALL_VARIANTS,
    SubtreeTag::fromString('some_tag'),
));

Read tags

$node = $subgraph->findNodeById($nodeAggregateId);

// Render all tags of this node (explicit tags bold)
$node->tags->map(fn (SubtreeTag $tag, bool $isInherited) => $this->outputLine(' - %s', [$isInherited ? $tag->value : '<b>' . $tag->value . '</b>']));

Breaking change

This is a breaking change mainly because it extends the Node and Aggregate read models.
Also the NodeHiddenState projection (and its NodeHiddenStateFinder) were replaced, see neos/neos-ui#3741

A projection replay is not required because the deprecated NodeAggregateWasDisabled and NodeAggregateWasEnabled events are automatically up-casted!

Custom projections might have to be reworked if they handled those events!

Next steps

On it's own, this new feature does not bring a whole lot of value (apart from replacing the overly complex restriction edges and the somewhat hacky NodeHiddenStateProjection).
But it will be the foundation for the Neos 9.0 security framework

Resolves: #4550
Related: #3732

Related: neos/neos-ui#3741

Resolves: #4550
Related: #3732
With #4076 the `ContentSubgraph` was adjusted to use the Doctrine DBAL
QueryBuilder.
This change adjusts the `ContentGraph` implementation accordingly

# Conflicts:
#	Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php
@bwaidelich bwaidelich merged commit bfd43df into 9.0 Mar 15, 2024
10 checks passed
@bwaidelich bwaidelich deleted the feature/4550-subtree-tags branch March 15, 2024 14:21
* @param \Closure(SubtreeTag): mixed $callback
* @return array<mixed>
*/
public function map(\Closure $callback): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im just wondering if your pr readme is outdated, because

$node->tags->map(fn (SubtreeTag $tag, bool $isInherited) => $this->outputLine(' - %s', [$isInherited ? $tag->value : '<b>' . $tag->value . '</b>']));

doesnt seem to work?

And also i was also wondering why we return a string array if we already have toStringArray

Copy link
Member Author

@bwaidelich bwaidelich Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node::tags is a NodeTags instance, not a SubtreeTags

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay sorry thanks, my brain still holds the old state in memory will have too pull :)


public function getIterator(): \Traversable
{
return new \ArrayIterator(array_values($this->tags));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw we agreed on using yield from $array in these cases ^^

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, feel free to fix!

bwaidelich added a commit that referenced this pull request Mar 19, 2024
This is a follow-up to the Subtree Tags introduction (#4659) that removes the now unsued `VisibilityConstraints::isDisabledContentShown()`

*Note:* The implementation of this method was incorrect but instead of fixing that I decided to remove it since we should no longer rely on this and instead refer to the public `VisibilityConstraints::tagConstraints` field

Related #4550
mhsdesign added a commit to mhsdesign/neos-development-collection that referenced this pull request Dec 10, 2024
…d spread around

This overhauls the `NodeAggregateWasDisabled` upcasting from

neos#4659
neos-bot pushed a commit to neos/contentrepository-core that referenced this pull request Dec 12, 2024
…d spread around

This overhauls the `NodeAggregateWasDisabled` upcasting from

neos/neos-development-collection#4659
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce Subtree Tags
3 participants