Skip to content

Commit d1988ae

Browse files
Jean-Beruphansys
andauthored
[Tree][NestedSet] Fix TreeRoot without rootIdentifierMethod when calling getNextSiblings
* [Tree] Fix TreeRoot without rootIdentifierMethod when calling getNextSiblings * Update tests/Gedmo/Tree/Fixture/Issue2517/Category.php Co-authored-by: Javier Spagnoletti <[email protected]> * update changelog Co-authored-by: Javier Spagnoletti <[email protected]>
1 parent fcdcc29 commit d1988ae

File tree

4 files changed

+218
-2
lines changed

4 files changed

+218
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ a release.
1818
---
1919

2020
## [Unreleased]
21+
### Fixed
22+
- Tree: TreeRoot without rootIdentifierMethod when calling getNextSiblings (#2518)
2123

2224
## [3.9.0] - 2022-09-22
2325
### Fixed

src/Tree/Entity/Repository/NestedTreeRepository.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,11 @@ public function getNextSiblingsQueryBuilder($node, $includeSelf = false)
444444
} elseif (isset($config['root'])) {
445445
$qb->andWhere($qb->expr()->eq('node.'.$config['root'], ':root'));
446446
$qb->andWhere($qb->expr()->isNull('node.'.$config['parent']));
447-
$method = $config['rootIdentifierMethod'];
448-
$qb->setParameter('root', $node->$method());
447+
$root = isset($config['rootIdentifierMethod']) ?
448+
$node->{$config['rootIdentifierMethod']}() :
449+
$wrapped->getPropertyValue($config['root'])
450+
;
451+
$qb->setParameter('root', $root);
449452
} else {
450453
$qb->andWhere($qb->expr()->isNull('node.'.$config['parent']));
451454
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Doctrine Behavioral Extensions package.
7+
* (c) Gediminas Morkevicius <[email protected]> http://www.gediminasm.org
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Gedmo\Tests\Tree\Fixture\Issue2517;
13+
14+
use Doctrine\Common\Collections\Collection;
15+
use Doctrine\DBAL\Types\Types;
16+
use Doctrine\ORM\Mapping as ORM;
17+
use Gedmo\Mapping\Annotation as Gedmo;
18+
use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
19+
20+
/**
21+
* @Gedmo\Tree(type="nested")
22+
* @ORM\Table(name="categories")
23+
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
24+
*/
25+
#[Gedmo\Tree(type: 'nested')]
26+
#[ORM\Table(name: 'categories')]
27+
#[ORM\Entity(repositoryClass: NestedTreeRepository::class)]
28+
class Category
29+
{
30+
/**
31+
* @var int|null
32+
*
33+
* @ORM\Column(name="id", type="integer")
34+
* @ORM\Id
35+
* @ORM\GeneratedValue
36+
*/
37+
#[ORM\Id]
38+
#[ORM\GeneratedValue]
39+
#[ORM\Column(type: Types::INTEGER)]
40+
private $id;
41+
42+
/**
43+
* @var string|null
44+
*
45+
* @ORM\Column(name="title", type="string", length=64)
46+
*/
47+
#[ORM\Column(name: 'title', type: Types::STRING, length: 64)]
48+
private $title;
49+
50+
/**
51+
* @var int|null
52+
*
53+
* @Gedmo\TreeLeft
54+
* @ORM\Column(name="lft", type="integer")
55+
*/
56+
#[ORM\Column(name: 'lft', type: Types::INTEGER)]
57+
#[Gedmo\TreeLeft]
58+
private $lft;
59+
60+
/**
61+
* @var int|null
62+
*
63+
* @Gedmo\TreeRight
64+
* @ORM\Column(name="rgt", type="integer")
65+
*/
66+
#[ORM\Column(name: 'rgt', type: Types::INTEGER)]
67+
#[Gedmo\TreeRight]
68+
private $rgt;
69+
70+
/**
71+
* @var int|null
72+
*
73+
* @Gedmo\TreeLevel
74+
* @ORM\Column(name="lvl", type="integer")
75+
*/
76+
#[ORM\Column(name: 'lvl', type: Types::INTEGER)]
77+
#[Gedmo\TreeLevel]
78+
private $lvl;
79+
80+
/**
81+
* @var self|null
82+
*
83+
* @Gedmo\TreeRoot
84+
* @ORM\ManyToOne(targetEntity="Category")
85+
* @ORM\JoinColumn(name="tree_root", referencedColumnName="id", onDelete="CASCADE")
86+
*/
87+
#[Gedmo\TreeRoot]
88+
#[ORM\ManyToOne(targetEntity: self::class)]
89+
#[ORM\JoinColumn(name: 'tree_root', referencedColumnName: 'id', onDelete: 'CASCADE')]
90+
private $root;
91+
92+
/**
93+
* @var self|null
94+
*
95+
* @Gedmo\TreeParent
96+
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
97+
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
98+
*/
99+
#[Gedmo\TreeParent]
100+
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
101+
#[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
102+
private $parent;
103+
104+
/**
105+
* @var Collection<int, Category>
106+
*
107+
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
108+
* @ORM\OrderBy({"lft" = "ASC"})
109+
*/
110+
#[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')]
111+
#[ORM\OrderBy(['lft' => 'ASC'])]
112+
private $children;
113+
114+
public function getId(): ?int
115+
{
116+
return $this->id;
117+
}
118+
119+
public function setTitle(?string $title): void
120+
{
121+
$this->title = $title;
122+
}
123+
124+
public function getTitle(): ?string
125+
{
126+
return $this->title;
127+
}
128+
129+
public function getRoot(): ?self
130+
{
131+
return $this->root;
132+
}
133+
134+
public function setParent(?self $parent): void
135+
{
136+
$this->parent = $parent;
137+
}
138+
139+
public function getParent(): ?self
140+
{
141+
return $this->parent;
142+
}
143+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Doctrine Behavioral Extensions package.
7+
* (c) Gediminas Morkevicius <[email protected]> http://www.gediminasm.org
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Gedmo\Tests\Tree\Issue;
13+
14+
use Doctrine\Common\EventManager;
15+
use Gedmo\Tests\Tool\BaseTestCaseORM;
16+
use Gedmo\Tests\Tree\Fixture\Issue2517\Category;
17+
use Gedmo\Tree\TreeListener;
18+
19+
final class Issue2517Test extends BaseTestCaseORM
20+
{
21+
/**
22+
* @var TreeListener
23+
*/
24+
private $listener;
25+
26+
protected function setUp(): void
27+
{
28+
parent::setUp();
29+
30+
$this->listener = new TreeListener();
31+
32+
$evm = new EventManager();
33+
$evm->addEventSubscriber($this->listener);
34+
35+
$this->getDefaultMockSqliteEntityManager($evm);
36+
}
37+
38+
public function testGetNextSiblingsWithoutIdentifierMethod(): void
39+
{
40+
$food = new Category();
41+
$food->setTitle('Food');
42+
43+
$fruits = new Category();
44+
$fruits->setTitle('Fruits');
45+
$fruits->setParent($food);
46+
47+
$vegetables = new Category();
48+
$vegetables->setTitle('Vegetables');
49+
$vegetables->setParent($food);
50+
51+
$this->em->persist($food);
52+
$this->em->persist($fruits);
53+
$this->em->persist($vegetables);
54+
$this->em->flush();
55+
56+
$categoryRepository = $this->em->getRepository(Category::class);
57+
58+
static::assertTrue($categoryRepository->verify());
59+
static::assertCount(0, $categoryRepository->getNextSiblings($food));
60+
static::assertCount(1, $categoryRepository->getNextSiblings($fruits));
61+
static::assertCount(0, $categoryRepository->getNextSiblings($vegetables));
62+
}
63+
64+
protected function getUsedEntityFixtures(): array
65+
{
66+
return [Category::class];
67+
}
68+
}

0 commit comments

Comments
 (0)