Skip to content

Commit

Permalink
Fix materialized getChildrenQueryBuilder method with includeNode set to
Browse files Browse the repository at this point in the history
true.
  • Loading branch information
l3l0 committed Oct 9, 2013
1 parent 52de3fd commit 06829b9
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 19 deletions.
27 changes: 21 additions & 6 deletions lib/Gedmo/Tree/Entity/Repository/MaterializedPathRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,36 @@ public function getChildrenQueryBuilder($node = null, $direct = false, $sortByFi
->select($alias)
->from($config['useObjectClass'], $alias);
$expr = '';
$includeNodeExpr = '';

if (is_object($node) && $node instanceof $meta->name) {
$node = new EntityWrapper($node, $this->_em);
$nodePath = $node->getPropertyValue($path);
$expr = $qb->expr()->andx()->add(
$qb->expr()->like($alias.'.'.$path, $qb->expr()->literal($nodePath.(substr($nodePath, -1) != $separator ? $separator : '').'%'))
$qb->expr()->like(
$alias.'.'.$path,
$qb->expr()->literal(
$nodePath
. ($config['path_ends_with_separator'] ? '' : $separator) .'%'
)
)
);

if (!$includeNode) {
if ($includeNode) {
$includeNodeExpr = $qb->expr()->eq($alias.'.'.$path, $qb->expr()->literal($nodePath));
} else {
$expr->add($qb->expr()->neq($alias.'.'.$path, $qb->expr()->literal($nodePath)));
}

if ($direct) {
$expr->add(
$qb->expr()->not(
$qb->expr()->like($alias.'.'.$path, $qb->expr()->literal($nodePath.'%'.$separator.'%'.$separator))
));
$qb->expr()->orx(
$qb->expr()->eq($alias.'.'.$config['level'], $qb->expr()->literal($node->getPropertyValue($config['level']))),
$qb->expr()->eq($alias.'.'.$config['level'], $qb->expr()->literal($node->getPropertyValue($config['level']) + 1))
)
);
}
} else if ($direct) {
} elseif ($direct) {
$expr = $qb->expr()->not(
$qb->expr()->like($alias.'.'.$path,
$qb->expr()->literal(
Expand All @@ -124,6 +135,10 @@ public function getChildrenQueryBuilder($node = null, $direct = false, $sortByFi
$qb->where('('.$expr.')');
}

if ($includeNodeExpr) {
$qb->orWhere('('.$includeNodeExpr.')');
}

$orderByField = is_null($sortByField) ? $alias.'.'.$config['path'] : $alias.'.'.$sortByField;
$orderByDir = $direction === 'asc' ? 'asc' : 'desc';
$qb->orderBy($orderByField, $orderByDir);
Expand Down
93 changes: 93 additions & 0 deletions tests/Gedmo/Tree/Fixture/MPCategoryWithTrimmedSeparator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Tree\Fixture;

use Gedmo\Tree\Node as NodeInterface;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\MaterializedPathRepository")
* @Gedmo\Tree(type="materializedPath")
*/
class MPCategoryWithTrimmedSeparator
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;

/**
* @Gedmo\TreePath(appendId=false, startsWithSeparator=false, endsWithSeparator=false)
* @ORM\Column(name="path", type="string", length=3000, nullable=true)
*/
private $path;

/**
* @Gedmo\TreePathSource
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;

/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="MPCategoryWithTrimmedSeparator", inversedBy="children")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
* })
*/
private $parentId;

/**
* @Gedmo\TreeLevel
* @ORM\Column(name="lvl", type="integer", nullable=true)
*/
private $level;

/**
* @ORM\OneToMany(targetEntity="MPCategoryWithTrimmedSeparator", mappedBy="parent")
*/
private $children;

public function getId()
{
return $this->id;
}

public function setTitle($title)
{
$this->title = $title;
}

public function getTitle()
{
return $this->title;
}

public function setParent(MPCategoryWithTrimmedSeparator $parent = null)
{
$this->parentId = $parent;
}

public function getParent()
{
return $this->parentId;
}

public function setPath($path)
{
$this->path = $path;
}

public function getPath()
{
return $this->path;
}

public function getLevel()
{
return $this->level;
}
}
98 changes: 85 additions & 13 deletions tests/Gedmo/Tree/MaterializedPathORMRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
class MaterializedPathORMRepositoryTest extends BaseTestCaseORM
{
const CATEGORY = "Tree\\Fixture\\MPCategory";
const CATEGORY_WITH_TRIMMED_SEPARATOR = "Tree\\Fixture\\MPCategoryWithTrimmedSeparator";

/** @var $this->repo \Gedmo\Tree\Entity\Repository\MaterializedPathRepository */
protected $repo;
Expand Down Expand Up @@ -116,6 +117,73 @@ function getChildren()
$this->assertEquals('Sports', $result[2]->getTitle());
}

/**
* @test
*/
function getChildrenForEntityWithTrimmedSeparators()
{
$meta = $this->em->getClassMetadata(self::CATEGORY_WITH_TRIMMED_SEPARATOR);
$this->populate(self::CATEGORY_WITH_TRIMMED_SEPARATOR);

$this->repo = $this->em->getRepository(self::CATEGORY_WITH_TRIMMED_SEPARATOR);
$root = $this->repo->findOneByTitle('Food');

// Get all children from the root, NOT including it
$result = $this->repo->getChildren($root, false, 'title');

$this->assertCount(4, $result);
$this->assertEquals('Carrots', $result[0]->getTitle());
$this->assertEquals('Fruits', $result[1]->getTitle());
$this->assertEquals('Potatoes', $result[2]->getTitle());
$this->assertEquals('Vegitables', $result[3]->getTitle());

// Get all children from the root, including it
$result = $this->repo->getChildren($root, false, 'title', 'asc', true);

$this->assertCount(5, $result);
$this->assertEquals('Carrots', $result[0]->getTitle());
$this->assertEquals('Food', $result[1]->getTitle());
$this->assertEquals('Fruits', $result[2]->getTitle());
$this->assertEquals('Potatoes', $result[3]->getTitle());
$this->assertEquals('Vegitables', $result[4]->getTitle());

// Get direct children from the root, NOT including it
$result = $this->repo->getChildren($root, true, 'title', 'asc');
$this->assertCount(2, $result);
$this->assertEquals('Fruits', $result[0]->getTitle());
$this->assertEquals('Vegitables', $result[1]->getTitle());

// Get direct children from the root, including it
$result = $this->repo->getChildren($root, true, 'title', 'asc', true);

$this->assertCount(3, $result);
$this->assertEquals('Food', $result[0]->getTitle());
$this->assertEquals('Fruits', $result[1]->getTitle());
$this->assertEquals('Vegitables', $result[2]->getTitle());

// Get ALL nodes
$result = $this->repo->getChildren(null, false, 'title');

$this->assertCount(9, $result);
$this->assertEquals('Best Whisky', $result[0]->getTitle());
$this->assertEquals('Carrots', $result[1]->getTitle());
$this->assertEquals('Drinks', $result[2]->getTitle());
$this->assertEquals('Food', $result[3]->getTitle());
$this->assertEquals('Fruits', $result[4]->getTitle());
$this->assertEquals('Potatoes', $result[5]->getTitle());
$this->assertEquals('Sports', $result[6]->getTitle());
$this->assertEquals('Vegitables', $result[7]->getTitle());
$this->assertEquals('Whisky', $result[8]->getTitle());

// Get ALL root nodes
$result = $this->repo->getChildren(null, true, 'title');

$this->assertCount(3, $result);
$this->assertEquals('Drinks', $result[0]->getTitle());
$this->assertEquals('Food', $result[1]->getTitle());
$this->assertEquals('Sports', $result[2]->getTitle());
}

/**
* @test
*/
Expand Down Expand Up @@ -277,48 +345,52 @@ public function test_changeChildrenIndex()
protected function getUsedEntityFixtures()
{
return array(
self::CATEGORY
self::CATEGORY,
self::CATEGORY_WITH_TRIMMED_SEPARATOR
);
}

public function createCategory()
public function createCategory($class = null)
{
$class = self::CATEGORY;
if (!$class) {
$class = self::CATEGORY;
}

return new $class;
}

private function populate()
private function populate($class = null)
{
$root = $this->createCategory();
$root = $this->createCategory($class);
$root->setTitle("Food");

$root2 = $this->createCategory();
$root2 = $this->createCategory($class);
$root2->setTitle("Sports");

$child = $this->createCategory();
$child = $this->createCategory($class);
$child->setTitle("Fruits");
$child->setParent($root);

$child2 = $this->createCategory();
$child2 = $this->createCategory($class);
$child2->setTitle("Vegitables");
$child2->setParent($root);

$childsChild = $this->createCategory();
$childsChild = $this->createCategory($class);
$childsChild->setTitle("Carrots");
$childsChild->setParent($child2);

$potatoes = $this->createCategory();
$potatoes = $this->createCategory($class);
$potatoes->setTitle("Potatoes");
$potatoes->setParent($child2);

$drinks = $this->createCategory();
$drinks = $this->createCategory($class);
$drinks->setTitle('Drinks');

$whisky = $this->createCategory();
$whisky = $this->createCategory($class);
$whisky->setTitle('Whisky');
$whisky->setParent($drinks);

$bestWhisky = $this->createCategory();
$bestWhisky = $this->createCategory($class);
$bestWhisky->setTitle('Best Whisky');
$bestWhisky->setParent($whisky);

Expand Down

0 comments on commit 06829b9

Please sign in to comment.