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

Tree rebuilding problem #2

Closed
AlexJMcloud opened this issue Jan 9, 2023 · 10 comments
Closed

Tree rebuilding problem #2

AlexJMcloud opened this issue Jan 9, 2023 · 10 comments

Comments

@AlexJMcloud
Copy link

When setting the position higher, the remaining elements are shifted out of position order
1111
11112
11113

How to make the rebuild work correctly?
Insert new element
$this->tree->reBuildPosition($insert_id, (int)$data['bra_pos'], $parent); $this->tree->rebuild();

Update element:
$this->tree->reBuildPosition($id, (int)$data['bra_pos'], $parent); $this->tree->rebuild();

@ve3
Copy link
Contributor

ve3 commented Jan 9, 2023

Hello,

These are examples in tests folders
https://github.com/Rundiz/nested-set/tree/version1/tests/phpunit/PHP71
https://github.com/Rundiz/nested-set/tree/version1/tests/phpunit/PHPB71
and https://github.com/Rundiz/nested-set/tree/version1/tests/via-http

In case you want quick fix you can compare with those code.

............................

However, Do you have sample DB data for run on my side to check and test?
Please included all relevant code & sample DB data to reproduce the problem because currently I cannot check anything with little data/debug info.

Do you use listTaxonomy(), or listTaxonomyFlatten() to list the data? If you check from samples in the tests folder, they use these methods to listing properly.

This class don't have reBuildPosition() method. With just the code called to that method, I cannot check that what it is.

If you call rebuild() without any arguments, it will be rebuild all data in selected table. So, it should be display correctly if you listing with certain methods or correctly use order by left column.

@AlexJMcloud
Copy link
Author

AlexJMcloud commented Jan 9, 2023

public function reBuildPosition(int $id, int $pos, int $parent): void
    {
        $getParents = $this->pdo->table($this->tableName)->
            where($this->parentIdColumnName . '= ? AND '. $this->positionColumnName . '>= ? AND '. $this->idColumnName . '!= ?', [$parent, $pos, $id])->getAll();
        if($getParents)
        {
            $i = $pos+1;
            foreach ($getParents as $item)
            {
                $this->pdo->table($this->tableName)->where($this->idColumnName, $item->{$this->idColumnName})->
                update([$this->positionColumnName => $i]);
                $i++;
            }
        }
    }

I have already added this class method myself. Taking as a basis the work of the class (when rebuilding the tree, an array of data is obtained based on the position of the element).

@AlexJMcloud
Copy link
Author

AlexJMcloud commented Jan 9, 2023

And to display the tree, I use a very simple query.
Select * From brand Order by bra_lft

@AlexJMcloud
Copy link
Author

Your method uses data based on element position: getTreeWithChildren.
After receiving the data, you are rebuilding the tree based on the array obtained by this method.

@ve3
Copy link
Contributor

ve3 commented Jan 10, 2023

The position number is based on the same level only. That means if you have 1.1 that is under parent Root 1, its position must be always start from 1.

I have added the sample code of management that is included Create/Read/Update/Delete.
See https://github.com/Rundiz/nested-set/tree/version1/tests/via-http/management

I've tested and everything work as expect but please read the note about manually process position number.

@AlexJMcloud
Copy link
Author

Thank you. But I will have to do all the same automatic change of positions within the same level.

@AlexJMcloud
Copy link
Author

I found the problem. When getting an array for position renumbering, I forgot to do the sorting. Added and everything worked as it should. So you can add this method to the class to automatically rebuild the position within the same level.

@AlexJMcloud AlexJMcloud reopened this Jan 10, 2023
@AlexJMcloud
Copy link
Author

`
public function reBuildPosition(int $id, int $pos, int $parent): void
{
$getParents = $this->pdo->table($this->tableName)->
where($this->parentIdColumnName . '= ? AND '. $this->positionColumnName . '>= ? AND '. $this->idColumnName . '!= ?', [$parent, $pos, $id])
->orderBy($this->positionColumnName)->getAll();
if($getParents)
{
$i = $pos+1;
foreach ($getParents as $item)
{
$this->pdo->table($this->tableName)->where($this->idColumnName, $item->{$this->idColumnName})->
update([$this->positionColumnName => $i]);
$i++;
}
}
}

`

@ve3
Copy link
Contributor

ve3 commented Jan 10, 2023

Thank you for your participation but I couldn't use that code because some reasons.

  1. That code is based on something like ORM or maybe query builder that pdo property isn't native PHP's \PDO class.
  2. There are a lot of ways to re-order position and some JS use or send data differently. So, it is not easy to handle these data and rebuild all the position number when re-order position. Unlike rebuild level, left, right that no one should manually update them and just let this class update the data because they need special algorithm to calculate.

I've tried to create that before but in the end, it will not work if some JS send weird data and it looks like the position can be update in many ways.

Thanks again.

@AlexJMcloud
Copy link
Author

Thank you for your participation but I couldn't use that code because some reasons.

  1. That code is based on something like ORM or maybe query builder that pdo property isn't native PHP's \PDO class.
  2. There are a lot of ways to re-order position and some JS use or send data differently. So, it is not easy to handle these data and rebuild all the position number when re-order position. Unlike rebuild level, left, right that no one should manually update them and just let this class update the data because they need special algorithm to calculate.

I've tried to create that before but in the end, it will not work if some JS send weird data and it looks like the position can be update in many ways.

Thanks again.

The query is really built not on pure \PDO, but on the query builder (php \PDO basis). But I can help with sql:
Select * FROM ' . $this->table . ' WHERE ' . $this->parentIdColumnName . '= ' . $parent . ' AND '. $this->positionColumnName . '>= ' . $pos . ' AND '. $this->idColumnName . '!= ' . $id . ';'
And so I have implemented without js. A form is filled in, where there is a field with the ability to put down the position number.

I send the element id, position number and parent element number to the function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants