Skip to content

Commit

Permalink
[Tree] recover() supports multiple fields in sortByField and `sor…
Browse files Browse the repository at this point in the history
…tDirection` option
  • Loading branch information
damianz5 authored and phansys committed Jun 19, 2023
1 parent 0db3937 commit 774a11f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ a release.
## [Unreleased]
### Added
- Tree: `setSibling()` and `getSibling()` methods in the `Node` interface through the BC `@method` annotation
- Tree: Support array of fields and directions in the `$sortByField` and `$direction` parameters at `AbstractTreeRepository::recover()`

### Changed
- Named arguments have precedence over the values passed in the `$data` array in annotation classes at `Gedmo\Mapping\Annotation\`
Expand Down
4 changes: 2 additions & 2 deletions doc/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -1224,8 +1224,8 @@ And that's it!
There are repository methods that are available for you in all the strategies:

* **getRootNodes** / **getRootNodesQuery** / **getRootNodesQueryBuilder**: Returns an array with the available root nodes. Arguments:
- *sortByField*: An optional field to order the root nodes. Defaults to "null".
- *direction*: In case the first argument is used, you can pass the direction here: "asc" or "desc". Defaults to "asc".
- *sortByField*: array<string> || string - An optional array of fields or field to order the root nodes. Defaults to "null".
- *direction*: array<string> || string - In case the first argument is used, you can pass the direction here: array of values or single value: "asc" or "desc". Defaults to "asc".
* **getChildren** / **getChildrenQuery** / **getChildrenQueryBuilder**: Returns an array of children nodes. Arguments:
- *node*: If you pass a node, the method will return its children. Defaults to "null" (this means it will return ALL nodes).
- *direct*: If you pass true as a value for this argument, you'll get only the direct children of the node
Expand Down
8 changes: 4 additions & 4 deletions src/Tree/Entity/Repository/AbstractTreeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ public function getChildrenIndex()
/**
* Get all root nodes query builder
*
* @param string|null $sortByField Sort by field
* @param string $direction Sort direction ("asc" or "desc")
* @param string|string[]|null $sortByField Sort by field
* @param string|string[] $direction Sort direction ("asc" or "desc")
*
* @return QueryBuilder QueryBuilder object
*/
Expand All @@ -175,8 +175,8 @@ abstract public function getRootNodesQueryBuilder($sortByField = null, $directio
/**
* Get all root nodes query
*
* @param string|null $sortByField Sort by field
* @param string $direction Sort direction ("asc" or "desc")
* @param string|string[]|null $sortByField Sort by field
* @param string|string[] $direction Sort direction ("asc" or "desc")
*
* @return Query Query object
*/
Expand Down
11 changes: 9 additions & 2 deletions src/Tree/Entity/Repository/ClosureTreeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ public function getRootNodesQueryBuilder($sortByField = null, $direction = 'asc'
->from($config['useObjectClass'], 'node')
->where('node.'.$config['parent'].' IS NULL');

if ($sortByField) {
$qb->orderBy('node.'.$sortByField, 'asc' === strtolower($direction) ? 'asc' : 'desc');
if (null !== $sortByField) {
$sortByField = (array) $sortByField;
$direction = (array) $direction;
foreach ($sortByField as $key => $field) {
$fieldDirection = $direction[$key] ?? 'asc';
if ($meta->hasField($field) || $meta->isSingleValuedAssociation($field)) {
$qb->addOrderBy('node.'.$field, 'asc' === strtolower($fieldDirection) ? 'asc' : 'desc');
}
}
}

return $qb;
Expand Down
9 changes: 8 additions & 1 deletion src/Tree/Entity/Repository/NestedTreeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,14 @@ public function getRootNodesQueryBuilder($sortByField = null, $direction = 'asc'
;

if (null !== $sortByField) {
$qb->orderBy('node.'.$sortByField, 'asc' === strtolower($direction) ? 'asc' : 'desc');
$sortByField = (array) $sortByField;
$direction = (array) $direction;
foreach ($sortByField as $key => $field) {
$fieldDirection = $direction[$key] ?? 'asc';
if ($meta->hasField($field) || $meta->isSingleValuedAssociation($field)) {
$qb->addOrderBy('node.'.$field, 'asc' === strtolower($fieldDirection) ? 'asc' : 'desc');
}
}
} else {
$qb->orderBy('node.'.$config['left'], 'ASC');
}
Expand Down
23 changes: 23 additions & 0 deletions tests/Gedmo/Tree/NestedTreeRootRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,29 @@ public function testShouldHandleAdvancedRepositoryFunctions(): void
static::assertSame(2, $potatoes->getLeft());
static::assertSame(3, $potatoes->getRight());

// recover with specified order with multiple fields

$repo->recover([
'flush' => true,
'treeRootNode' => $repo->find(1),
'skipVerify' => true,
'sortByField' => [
0 => 'title',
1 => 'title',
],
'sortDirection' => [
0 => 'ASC',
1 => 'DESC',
],
]);
static::assertTrue($repo->verify());

$this->em->clear();
$potatoes = $repo->findOneBy(['title' => 'Potatoes']);

static::assertSame(8, $potatoes->getLeft());
static::assertSame(9, $potatoes->getRight());

// test fast recover

$dql = 'UPDATE '.self::CATEGORY.' node';
Expand Down

0 comments on commit 774a11f

Please sign in to comment.