-
-
Notifications
You must be signed in to change notification settings - Fork 225
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: Soft removal subtree tag removed
#5463
Conversation
Allows for soft deletion and querying the node correctly within the projection while marked deleted.
okay just for reference: This change implements soft-removal as discussed here under "soft removal of nodes in the graph projection". With that we can solve the bug of not being able to interpret changes inside deleted hierarchies. Further it should also fixe the problem of having nodes moved out of a deleted tree part which is published: #5364. regarding the implementation: i would say that the change projection should no longer be able to handle the real
we could even think about (deprecating) and translating regarding the new policy: shouldn't the deleted condition will be hardcoded in the CR Auth Service so in Neos.Neos a subgraph is never fetched with deleted nodes?. For the workspace publishing service we could use the manual way of |
I guess we could do that, but wouldn't we need to offer some kind of migration for beta users? Or do we add a huge warning that people should publish/discard workspaces before updating to this?
Mmmm, I am happy to do it either way, deleted could indeed be hardcoded if we wanted. I guess any special use, say a trash can or so, can easily use the low level apis to access it.... Either way would be fine by me. |
Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Dto/SubtreeTag.php
Outdated
Show resolved
Hide resolved
We dont make it a policy because no one should have "Neos.Neos:ContentRepository.ReadDeletedNodes" granted
with the soft deletion - by tagging a node `deleted` - actual node deletions via (NodeAggregateWasRemoved) inside a non-live workspace are not desired in Neos if we publish a site we will include real removals like that in the publish or discard operation to prevent the change from being orphaned. Note that the site might not necessarily be the site where the change was made in multisite environments, but we cannot determine the hierarchy for removed nodes and edges.
because nodes are just tagged deleted we can still find them and their ancestors via the subgraph
okay i got rid of the removal attachment point flag now and also tested it in combination with the neos ui change and the ui e2e tests are fine as well left open points:
|
https://github.com/neos/neos-development-collection/pull/5463/files#diff-7afd4d9a8fcb7259c9136da8cba0e3b5b84fab7f01043a9a3c5ab54c881efc54R233 Should've taken care of the workspace ui problem? I saw that as well and after adjusting this here so that changes are marked as deleted it showed up as deleted in the workspace UI. |
ok the link doesn't work, but it's in the ChangeProjectino where a if $event->tag == deleted results in a deleted change |
this aligns more to our wording in `NodeAggregateWasRemoved` and we used generally the term 'remove' in neos 9
Regarding
Aside from many constraint checks and write site parts in the core (where the use of These are the other cases i found:
|
via the neos auth provider we will see disabled nodes in the backed (because its enabled for editor roles) but not the `removed` nodes which is correct. The restricted subtree tags are: array(1) { [0]=> string(7) "removed" }
removed
Todos as we discussed in the weekly last Friday:
further things, bernhard checked all handlers for
Also we still have these cases to adjust where we now want to avoid having removed nodes shown up
|
The removed tagging is NOT a core concern, and thus we create a dedicated factory similar to our `ContentStreamEventStreamName` factory.
and move logic out of `ContentRepositoryAuthorizationService` agian
because there is no sane default for a fully extensible standalone case. Instead, everyone should create their own default factory. The `default` implementation is left intact and extended to also hide `removed` nodes to be backwards compatible with previous neos cms betas.
…rojection by using the raw event Initially all `removalAttachmentPoint` handing logic was removed (neos#4487) With the migration strategy that only PublishSite would publish them with beta 19. This is to much of a breaking change as it will confuse editors because removed child nodes will no longer be publishable within a document or even be shown as changed. Instead, we fully handle the previously happened removed events as before when it comes to change indication and publishing via the neos ui. Once all projects are on the latest beta and have no legacy removal events we can remove the handling here as well. This might be either when we refactor the change projection or with Neos 9.1 The method `isChangeWithSelfReferencingRemovalAttachmentPoint` has not been reintroduced because since Neos 9 Beta 8 this imposes no longer a problem. See original change: neos#4943
…low rebasing old removals :( ^ sad face Without `RemoveNodeAggregate::fromArray` allowing this, on rebase old removals will be stripped of this property and will no longer be properly shown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay the change is now finished (and its followup prs too)
I hoped we could fully get rid of the removalAttachmentPoint: #4487
instead this pr merely prepares the full removal of this hack.
main point why i think we still need it in the core for now is to allow a fluid migration from existing workspaces when updating to beta 19.
That means legacy removes of contents on a document are still publishable and shown as changed when saying publish document.
I think we can remove the removalAttachmentPoint at any point later we like - probably already Neos 9.1.
Behaviour of the soft removal publishing e.g. which events are included will be document by test via #5494. That pr also shows how hard removals (without removalAttachmentPoint) will not be publishable in any way via the workspace publishing service -> as currently too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the change in general!
Just a few, partly nitpicky, comments regarding method names and an argument against the new classes NeosVisibilityConstraints
and SoftRemovedTag
* | ||
* Nodes for example with tag disabled will be findable | ||
*/ | ||
public static function createEmpty(): self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: wouldn't VisibilityConstraints::none()
be more descriptive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought so too but none()
as factory for collection objects is not present for any api in Neos. A few usages to internal objects have been sneakily introduced via your subscription change but they are all internal and ill rename them probably to createEmpty
too ^^
We had a similar naming conflict when introducing createWithoutDimensions
in #4632
so maybe we can go also the road of createWithoutConstraints
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of principle i of course DID open that can of worms of none
vs createEmpty
: #5497
Just to avoid running into that wormhole @kitsunet and me also discussed
VisibilityConstraints::excludeNone()
VisibilityConstraints::withoutExclude()
but after all we have done enough optimisation for now and will keep it createEmpty
.
Objection overruled.
* VisibilityConstraints::fromTagConstraints(SubtreeTags::create( | ||
* SubtreeTag::disabled()) | ||
* ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Not changed with this PR, but since it changes the API of this class: this constructor should be deprecated in favor of a new one VisibilityConstraints::fromSubtreeTags()
IMO. What are "tag constraints"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jup youre reading my mind! I had this change already in my local working directory an decided not to do that because it was just a recent addition of yours.
But as you feel the same - and seeing this is a brand new fresh api with little to no usages, we can definitely rename it without risking any likely breaking things!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we just decided for NeosVisibilityConstraints::excludeDisabled
how about the idea to carry the Exclude wording also down the line meaning:
final readonly class VisibilityConstraints
{
private function __construct(
public SubtreeTags $excludedSubtreeTags,
) {
}
public static function excludeSubtreeTags(SubtreeTags $tagConstraints): self;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adjusted via abd571e
* | ||
* @Flow\Proxy(false) | ||
*/ | ||
final readonly class SoftRemovedTag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't understood why we do
SubtreeTag::disabled()
but
SoftRemovedTag::getSubtreeTag()
Yet another abstraction is not really helpful IMO
What about simply doing sth like:
final readonly class NeosSubtreeTags {
public static function disabled(): SubtreeTag {
return SubtreeTag::fromString('disabled');
}
public static function removed(): SubtreeTag {
return SubtreeTag::fromString('removed');
}
}
?
This way we can make this a pure Neos concept and still avoid the magic strings to spread.
Instead of SoftRemovedTag::isRemovedSubtreeTag($tag)
you'd write $tag->equals(NeosSubtreeTags::removed())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the suggestion to fully move out the disabled
concern from the core is what i do really like. It also is what convinced me to implement: #5496
I introduced a NeosSubtreeTag
as you said and let extend the pr #5496 to specify also a disabled
constructor and have it deprecated in the core.
see commit 632b216
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of a SoftRemovedTag
came from the wrapper objects ContentStreamEventStreamName
and WorkspaceEventStreamName
where we could have had also a ContentRepositoryEventStream
object or something...
I guess a SoftRemovedTag
and aDeletedTag
objects are not too bad and can actually be nicely encapsulated into their own contexts/ folders but having a NeosSubtreeTags
seems indeed the better choice to have it all in one place
`frontend()` suggests that these are the default visibility constraints for the Neos frontend. But the default visibility constraints are determined by the ContentRepositoryAuthorizationService. Instead we introduce in combination with `VisibilityConstraints::merge` a way to combine two sets of visibility constraints to be able to write ``` NeosVisibilityConstraints::withoutRemoved() ->merge(NeosVisibilityConstraints::withoutDisabled()) ```
…reateEmpty()` We had the discussion again how to name an empty object and for normal collections we used `createEmpty()` in the past and should continue to do so. The use of `none()` snuck in lately via the subscription engine. neos#5463 (comment)
After the discussion https://neos-project.slack.com/archives/C04PYL8H3/p1741197705659749?thread_ts=1741193962.566189&cid=C04PYL8H3 We concluded that `without` is misleading and normally used either way for immutable object member methods.
The method is relatively new from beta 16 and seldom used: neos@14c9f84 to be au pair to `NeosVisibilityConstraints::excludeDisabled` Also we had the discussion that the naming neos#5463 (comment) "TagConstraints" is confusing because there is no such value object. Funnily this reverts neos@f1c66a3 which was just a wip.
And deprecate `SubtreeTag::disabled` see discussion in neos#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
The method is relatively new from beta 16 and seldom used: neos/neos-development-collection@14c9f84 to be au pair to `NeosVisibilityConstraints::excludeDisabled` Also we had the discussion that the naming neos/neos-development-collection#5463 (comment) "TagConstraints" is confusing because there is no such value object. Funnily this reverts neos/neos-development-collection@9372b79 which was just a wip.
The method is relatively new from beta 16 and seldom used: neos/neos-development-collection@f3bc82e to be au pair to `NeosVisibilityConstraints::excludeDisabled` Also we had the discussion that the naming neos/neos-development-collection#5463 (comment) "TagConstraints" is confusing because there is no such value object. Funnily this reverts neos/neos-development-collection@702839d which was just a wip.
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
The method is relatively new from beta 16 and seldom used: neos/neos-development-collection@14c9f84 to be au pair to `NeosVisibilityConstraints::excludeDisabled` Also we had the discussion that the naming neos/neos-development-collection#5463 (comment) "TagConstraints" is confusing because there is no such value object. Funnily this reverts neos/neos-development-collection@f1c66a3 which was just a wip.
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
The method is relatively new from beta 16 and seldom used: neos/neos-development-collection@4a230cc to be au pair to `NeosVisibilityConstraints::excludeDisabled` Also we had the discussion that the naming neos/neos-development-collection#5463 (comment) "TagConstraints" is confusing because there is no such value object. Funnily this reverts neos/neos-development-collection@f1c66a3 which was just a wip.
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
And deprecate `SubtreeTag::disabled` see discussion in neos/neos-development-collection#5463 (comment) The only behavioural change is that with that the content repository does not know any subtree tag by default and thus the new default of the `StaticAuthProvider::getVisibilityConstraints` is to have nothing excluded!
Allows for soft deletion and querying the node correctly within the projection while marked deleted.
This change implements soft-removal as discussed #5459 (comment) under "soft removal of nodes in the graph projection". With that we can solve the #4997 of not being able to interpret changes inside deleted hierarchies. Further it should also fixe the problem of having nodes moved out of a deleted tree part which is published: #5364.