Skip to content

Conversation

@robinroloff
Copy link
Contributor

@robinroloff robinroloff commented Oct 21, 2025

This PR adds the option to filter for included subtree tags. It also adds the first tests for filtering custom subtree tags.

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch
  • Reviewer - PR Title is brief but complete and starts with FEATURE|TASK|BUGFIX
  • Reviewer - The first section explains the change briefly for change-logs
  • Reviewer - Breaking Changes are marked with !!! and have upgrade-instructions

@robinroloff robinroloff changed the title Include Subtree Tags + Tests FEATURE: Include Subtree Tags + Tests Oct 21, 2025
@robinroloff
Copy link
Contributor Author

first draft as discussed @skurfuerst

@skurfuerst
Copy link
Member

I will give feedback tonight (or merge into my branch :))

Copy link
Member

@skurfuerst skurfuerst left a comment

Choose a reason for hiding this comment

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

Hey @robinroloff ,

very cool, thanks for your contribution :) I have added some notes to make this all easier to review and reason about.

Thanks and all the best, Sebastian

public function findDescendantNodes(NodeAggregateId $entryNodeAggregateId, FindDescendantNodesFilter $filter): Nodes
{
['queryBuilderInitial' => $queryBuilderInitial, 'queryBuilderRecursive' => $queryBuilderRecursive, 'queryBuilderCte' => $queryBuilderCte] = $this->buildDescendantNodesQueries($entryNodeAggregateId, $filter);
[
Copy link
Member

Choose a reason for hiding this comment

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

can you please revert the auto-format? in this file? It's very hard to find out the actual change :)

$queryBuilder->setParameter('tagPath' . $i, '$."' . $includedTag->value . '"');
$i++;
}
$where = '(' . implode(' OR ', $includedParts) . ')';
Copy link
Member

Choose a reason for hiding this comment

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

hm, unsure if we should rather use the Nested query Builders using the expr() API here :) How are complex queries in this file otherwise constructed? (I'd keep it similar)

docs -> https://www.doctrine-project.org/projects/doctrine-dbal/en/4.3/reference/query-builder.html#building-expressions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, changed that, I'm not sure if I did it right though. Kinda feels more hacky than before.

Background:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | mul, de, en, ch | ch->de->mul, en->mul |
Copy link
Member

Choose a reason for hiding this comment

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

Given no content dimensions (or the like) -> makes the test easier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, to be honest I just copied the background from another feature. I will remove all the unnecessary stuff.

Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | mul, de, en, ch | ch->de->mul, en->mul |
And using the following node types:
Copy link
Member

Choose a reason for hiding this comment

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

can we come up with a minmal example? :) i.e. remove all node types you do not need to make the test easier to read

| a2b | a2b | Neos.ContentRepository.Testing:Page | a2 | {} | {} |
| a2b1 | a2b1 | Neos.ContentRepository.Testing:Page | a2b | {} | {} |
| b | b | Neos.ContentRepository.Testing:Page | home | {} | {} |
And the command DisableNodeAggregate is executed with payload:
Copy link
Member

Choose a reason for hiding this comment

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

do we need disable + move? I think not :)

* @param SubtreeTags $excluded A set of {@see SubtreeTag} instances that will be _excluded_ from the results of any content graph query
* @param SubtreeTags $included A set of {@see SubtreeTag} instances that will be _included_ in the results of any content graph query
*/
public static function excludeAndIncludeSubtreeTags(SubtreeTags $excluded, SubtreeTags $included): self
Copy link
Member

Choose a reason for hiding this comment

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

I am still very unsure about the public API here. IMHO we need a better wording for "include and exclude is both set" -> something which makes really clear that "included" comes first and excluded always win. Maybe something like "base subtree tags" and "excluded".

-> we can first merge it now, and later rename (before we merge the upstream PR)

Copy link
Contributor Author

@robinroloff robinroloff Oct 21, 2025

Choose a reason for hiding this comment

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

Me too, I wasn't sure either, this is the main reason why this PR is still a draft.

My suggestion would be to make the VisibilityConstraints a builder pattern, but as I didn't find them anywhere else in the code base, I wasn't sure what your standard for that is.
However, I feel like it would make a lot of sense for easy usage and for future extensibility.

@skurfuerst skurfuerst marked this pull request as ready for review October 22, 2025 11:40
@skurfuerst
Copy link
Member

skurfuerst commented Oct 22, 2025

FYI (for anybody stumbling across this PR here): NOT merging into Neos 9, but into our dev branch!

@skurfuerst skurfuerst merged commit 36ae60f into neos:feat-security-permissions Oct 22, 2025
2 checks passed
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.

2 participants