Skip to content
Permalink
Browse files

Fix bidirectionnal issues

  • Loading branch information...
Pierstoval committed Jul 16, 2016
1 parent c30b8fd commit ff80a818b20b13f69c83e9ce6d2af80ee5a5d753
Showing with 99 additions and 27 deletions.
  1. +26 −10 Entity/Category.php
  2. +13 −2 Entity/Page.php
  3. +60 −15 EventListener/DoctrineMappingListener.php
@@ -70,6 +70,11 @@ abstract class Category
*/
protected $children;
/**
* @var Page[]|ArrayCollection
*/
protected $pages;
public function __toString()
{
return $this->name;
@@ -79,6 +84,7 @@ public function __construct()
{
$this->createdAt = new \DateTime();
$this->children = new ArrayCollection();
$this->pages = new ArrayCollection();
}
/**
@@ -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
*/
@@ -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;
}
@@ -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)
{
@@ -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);
@@ -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
*/
@@ -385,6 +392,10 @@ public function addChild(Page $page)
{
$this->children->add($page);
if ($page->getParent() !== $this) {
$page->setParent($this);
}
return $this;
}
@@ -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);
@@ -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.
You can’t perform that action at this time.