doRemoveLeaf() incorrectly clears leaf data and breaks subgroup trees

Created on 12 February 2021, almost 4 years ago
Updated 1 August 2024, 6 months ago

Problem/Motivation

When deleting the first subgroup in a hierarchy level, , the group leaf data can get incorrectly erased thus leading to broken subgroup hierarchies.

Steps to reproduce

(Partially copied from #3182801-2: An existing subgroup cannot be deleted )
- Created 2 group types Sub 1, and Sub 2 as a tree (Sub 1 is parent to Sub 2)
- Added group Test 1 of type Sub 1
-Aadded subgroup Test 2 of type Sub 2 to group Test 1
- Added subgroup Test 3 of type Sub 2 to group Test 1
- Call programatically to \Drupal\subgroup\Entity\SubgroupHandlerBase::getChildren() with "Test 1" as parameter. You will get 2 result: "Test 2" and "Test 3". Visit any subgroup listing (i.e. a view): you will see Test2 and Test 3.
- Delete Test 2
- Call programatically to \Drupal\subgroup\Entity\SubgroupHandlerBase::getChildren() with "Test 1" as parameter. You will get an empty result.

Proposed resolution

Don't rely on the child "left" and "right" values to undo a tree structure.

See comment #4 🐛 doRemoveLeaf() incorrectly clears leaf data and breaks subgroup trees Fixed

The problem is related to this code on function doRemoveLeaf() on /src/Entity/SubgroupHandlerBase.php

    // If the left and right values are 2 and 3 respectively it means we're
    // removing the last child of a tree root. In this case, we unset the tree
    // altogether.
    if ($leaf->getLeft() === 2 && $leaf->getRight() === 3) {
      $root = $this->storage->load($leaf->getTree());
      $this->clearLeafData($root, TRUE);
    }

The code states that "If the left and right values are 2 and 3 respectively it means we're removing the last child", but this is not true: it means we are removing the first

So, every time the first subgroup of a tree is removed, it will wipe the structure of the whole tree leading to unexpected results if there were any siblings still alive.

The proposed resolution is either to check wether there are more siblings left before calling clearLeafData or check the presence of descendants of the root

Remaining tasks

Test and review.
Fix failing tests.

User interface changes

None

API changes

None

Data model changes

None

🐛 Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

🇪🇸Spain akalam

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • I think this fix does not work anymore. I'm not sure why or how but we should check for a descendants count of 0, not 1. When I great 1 group with 2 subgroups and specifically delete the first subgroup. My tree gets broken because it triggers clearLeafData(). We only want this to trigger when there are no children in the root. Here is a new patch:

Production build 0.71.5 2024