Skip to content

Commit

Permalink
Fix bidirectionnal issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierstoval committed Jul 16, 2016
1 parent c30b8fd commit ff80a81
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 27 deletions.
36 changes: 26 additions & 10 deletions Entity/Category.php
Expand Up @@ -70,6 +70,11 @@ abstract public function getId();
*/
protected $children;

/**
* @var Page[]|ArrayCollection
*/
protected $pages;

public function __toString()
{
return $this->name;
Expand All @@ -79,6 +84,7 @@ public function __construct()
{
$this->createdAt = new \DateTime();
$this->children = new ArrayCollection();
$this->pages = new ArrayCollection();
}

/**
Expand Down Expand Up @@ -122,15 +128,15 @@ public function setDescription($description)
}

/**
* @return mixed
* @return string
*/
public function getSlug()
{
return $this->slug;
}

/**
* @param mixed $slug
* @param string $slug
*
* @return Category
*/
Expand Down Expand Up @@ -170,20 +176,26 @@ public function getParent()
}

/**
* @param mixed $parent
* @param Category|null $parent
*
* @return Category
*/
public function setParent(Category $parent = null)
{
if ($parent === $this) {
// Refuse the category to have itself as parent
// Refuse the category to have itself as parent.
$this->parent = null;

return $this;
}

$this->parent = $parent;

// Ensure bidirectional relation is respected.
if ($parent && false === $parent->getChildren()->indexOf($this)) {
$parent->addChild($this);
}

return $this;
}

Expand All @@ -204,21 +216,25 @@ public function getChildren()
}

/**
* @param Category $child
* @param Category $category
*
* @return Category[]
* @return Category
*/
public function addChild(Category $child)
public function addChild(Category $category)
{
$this->children->add($child);
$this->children->add($category);

if ($category->getParent() !== $this) {
$category->setParent($this);
}

return $this;
}

/**
* @param Category $child
*
* @return Category[]
* @return Category
*/
public function removeChild(Category $child)
{
Expand Down Expand Up @@ -264,7 +280,7 @@ public function updateSlug()
public function onRemove(LifecycleEventArgs $event)
{
$em = $event->getEntityManager();
if ($this->children) {
if (count($this->children)) {
foreach ($this->children as $child) {
$child->setParent(null);
$em->persist($child);
Expand Down
15 changes: 13 additions & 2 deletions Entity/Page.php
Expand Up @@ -358,16 +358,23 @@ public function getParent()
public function setParent(Page $parent = null)
{
if ($parent === $this) {
// Refuse the page to have itself as parent
// Refuse the category to have itself as parent.
$this->parent = null;

return $this;
}

$this->parent = $parent;

// Ensure bidirectional relation is respected.
if ($parent && false === $parent->getChildren()->indexOf($this)) {
$parent->addChild($this);
}

return $this;
}


/**
* @return Page[]|ArrayCollection
*/
Expand All @@ -385,6 +392,10 @@ public function addChild(Page $page)
{
$this->children->add($page);

if ($page->getParent() !== $this) {
$page->setParent($this);
}

return $this;
}

Expand Down Expand Up @@ -497,7 +508,7 @@ public function updateSlug()
public function onRemove(LifecycleEventArgs $event)
{
$em = $event->getEntityManager();
if ($this->children) {
if (count($this->children)) {
foreach ($this->children as $child) {
$child->setParent(null);
$em->persist($child);
Expand Down
75 changes: 60 additions & 15 deletions EventListener/DoctrineMappingListener.php
Expand Up @@ -53,41 +53,86 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
/** @var ClassMetadata $classMetadata */
$classMetadata = $eventArgs->getClassMetadata();

$isPage = is_a($classMetadata->getName(), $this->pageClass, true);
$isCategory = is_a($classMetadata->getName(), $this->categoryClass, true);

if (!$classMetadata->hasAssociation('parent') && is_a($classMetadata->getName(), $this->pageClass, true)) {
// Declare mapping for category
if ($isPage) {
$this->processPageMetadata($classMetadata);
$this->processParent($classMetadata, $this->pageClass);
$this->processChildren($classMetadata, $this->pageClass);
}

if ($isCategory) {
$this->processCategoryMetadata($classMetadata);
$this->processParent($classMetadata, $this->categoryClass);
$this->processChildren($classMetadata, $this->categoryClass);
}
}

/**
* Declare mapping for Page entity.
*
* @param ClassMetadata $classMetadata
*/
private function processPageMetadata(ClassMetadata $classMetadata)
{
if (!$classMetadata->hasAssociation('category')) {
$classMetadata->mapManyToOne([
'fieldName' => 'category',
'targetEntity' => $this->categoryClass,
'inversedBy' => 'pages',
]);
}
}

// Declare self-bidirectionnal mapping for parent/children
$classMetadata->mapManyToOne([
'fieldName' => 'parent',
'targetEntity' => $this->pageClass,
'inversedBy' => 'children',
]);
/**
* Declare mapping for Category entity.
*
* @param ClassMetadata $classMetadata
*/
private function processCategoryMetadata(ClassMetadata $classMetadata)
{
if (!$classMetadata->hasAssociation('pages')) {
$classMetadata->mapOneToMany([
'fieldName' => 'children',
'fieldName' => 'pages',
'targetEntity' => $this->pageClass,
'mappedBy' => 'parent',
'mappedBy' => 'category',
]);
}

if (!$classMetadata->hasAssociation('parent') && is_a($classMetadata->getName(), $this->categoryClass, true)) {
// Declare self-bidirectionnal mapping for parent/children
}

/**
* Declare self-bidirectionnal mapping for parent.
*
* @param ClassMetadata $classMetadata
* @param string $class
*/
private function processParent(ClassMetadata $classMetadata, $class)
{
if (!$classMetadata->hasAssociation('parent')) {
$classMetadata->mapManyToOne([
'fieldName' => 'parent',
'targetEntity' => $this->categoryClass,
'targetEntity' => $class,
'inversedBy' => 'children',
]);
}
}

/**
* Declare self-bidirectionnal mapping for children
*
* @param ClassMetadata $classMetadata
* @param string $class
*/
private function processChildren(ClassMetadata $classMetadata, $class)
{
if (!$classMetadata->hasAssociation('children')) {
$classMetadata->mapOneToMany([
'fieldName' => 'children',
'targetEntity' => $this->categoryClass,
'targetEntity' => $class,
'mappedBy' => 'parent',
]);

}
}
}

0 comments on commit ff80a81

Please sign in to comment.