Unverified Commit c6bb438e authored by Sebastian Castro's avatar Sebastian Castro
Browse files

Prevent circular reference between categories and options

parent 21b7df6d
...@@ -41,6 +41,11 @@ class CategoryAdmin extends AbstractAdmin ...@@ -41,6 +41,11 @@ class CategoryAdmin extends AbstractAdmin
protected function configureFormFields(FormMapper $formMapper) protected function configureFormFields(FormMapper $formMapper)
{ {
// prevent circular reference, i.e setting a child as parent
$repo = $this->getConfigurationPool()->getContainer()->get('doctrine_mongodb')->getRepository('BiopenGeoDirectoryBundle:Option');
$parentQuery = $repo->createQueryBuilder()
->field('id')->notIn($this->subject->getAllOptionsIds());
$formMapper $formMapper
->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6')) ->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6'))
->add('name', null, array('required' => true, 'label' => 'Nom du groupe')) ->add('name', null, array('required' => true, 'label' => 'Nom du groupe'))
...@@ -48,6 +53,7 @@ class CategoryAdmin extends AbstractAdmin ...@@ -48,6 +53,7 @@ class CategoryAdmin extends AbstractAdmin
->add('parent', 'sonata_type_model', array( ->add('parent', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Option', 'class'=> 'Biopen\GeoDirectoryBundle\Document\Option',
'required' => false, 'required' => false,
'query' => $parentQuery,
'choices_as_values' => true, 'choices_as_values' => true,
'label' => 'Catégorie parente'), array('admin_code' => 'admin.option_hidden')) 'label' => 'Catégorie parente'), array('admin_code' => 'admin.option_hidden'))
->add('isMandatory', null, array('required' => false, 'label' => "Choix obligatoire", 'label_attr' => ['title'=>"Une catégorie de ce groupe doit être obligatoirement selectionnée"])) ->add('isMandatory', null, array('required' => false, 'label' => "Choix obligatoire", 'label_attr' => ['title'=>"Une catégorie de ce groupe doit être obligatoirement selectionnée"]))
......
...@@ -21,7 +21,7 @@ use Knp\Menu\ItemInterface; ...@@ -21,7 +21,7 @@ use Knp\Menu\ItemInterface;
class OptionAdmin extends AbstractAdmin class OptionAdmin extends AbstractAdmin
{ {
protected $baseRouteName = 'admin_biopen_geodirectory_option'; protected $baseRouteName = 'admin_biopen_geodirectory_option';
protected $baseRoutePattern = 'admin_biopen_geodirectory_option'; protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
public function createQuery($context = 'list') public function createQuery($context = 'list')
{ {
...@@ -41,6 +41,11 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option'; ...@@ -41,6 +41,11 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
protected function configureFormFields(FormMapper $formMapper) protected function configureFormFields(FormMapper $formMapper)
{ {
// prevent circular reference, i.e setting a child as parent
$repo = $this->getConfigurationPool()->getContainer()->get('doctrine_mongodb')->getRepository('BiopenGeoDirectoryBundle:Category');
$parentQuery = $repo->createQueryBuilder()
->field('id')->notIn($this->subject->getAllSubcategoriesIds());
$formMapper $formMapper
->tab('Principal') ->tab('Principal')
->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6')) ->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6'))
...@@ -50,6 +55,7 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option'; ...@@ -50,6 +55,7 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
->add('parent', 'sonata_type_model', array( ->add('parent', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Category', 'class'=> 'Biopen\GeoDirectoryBundle\Document\Category',
'required' => true, 'required' => true,
'query' => $parentQuery,
'choices_as_values' => true, 'choices_as_values' => true,
'label' => 'Groupe de Catégorie parent', 'label' => 'Groupe de Catégorie parent',
'mapped' => true), array('admin_code' => 'admin.categories.lite_hidden')) 'mapped' => true), array('admin_code' => 'admin.categories.lite_hidden'))
......
...@@ -184,6 +184,23 @@ class Category ...@@ -184,6 +184,23 @@ class Category
return $sortedOptions; return $sortedOptions;
} }
public function getAllOptionsIds()
{
return $this->recursivelyGetOptionsIds($this);
}
private function recursivelyGetOptionsIds($category)
{
$result = [];
foreach ($category->getOptions() as $option) {
$result[] = $option->getId();
foreach ($option->getSubcategories() as $childCategory) {
$result = array_merge($result, $this->recursivelyGetOptionsIds($childCategory));
}
}
return $result;
}
/** /**
* Get id * Get id
* *
...@@ -409,11 +426,15 @@ class Category ...@@ -409,11 +426,15 @@ class Category
*/ */
public function setParent($parent, $updateParent = true) public function setParent($parent, $updateParent = true)
{ {
if ($parent && in_array($parent->getId(), $this->getAllOptionsIds())) {
// Circular reference
} else {
// clearing old parent // clearing old parent
if ($updateParent && $this->parent) $this->parent->removeSubcategory($this, false); if ($updateParent && $this->parent) $this->parent->removeSubcategory($this, false);
$this->parent = $parent; $this->parent = $parent;
if ($updateParent && $parent) $parent->addSubcategory($this, false); if ($updateParent && $parent) $parent->addSubcategory($this, false);
}
return $this; return $this;
} }
......
...@@ -192,6 +192,13 @@ class Option ...@@ -192,6 +192,13 @@ class Option
return $this->getName(); return $this->getName();
} }
public function allSubcategories()
{
$result = [];
return $result;
}
public function getNameWithParent() public function getNameWithParent()
{ {
$result = ''; $result = '';
...@@ -245,6 +252,23 @@ class Option ...@@ -245,6 +252,23 @@ class Option
return $result; return $result;
} }
public function getAllSubcategoriesIds()
{
return $this->recursivelyGetSubcategoriesIds($this);
}
private function recursivelyGetSubcategoriesIds($option)
{
$result = [];
foreach ($option->getSubcategories() as $categorie) {
$result[] = $categorie->getId();
foreach ($categorie->getOptions() as $childOption) {
$result = array_merge($result, $this->recursivelyGetSubcategoriesIds($childOption));
}
}
return $result;
}
public function getSubcategoriesCount() public function getSubcategoriesCount()
{ {
if ($this->subcategories) return $this->subcategories->count(); if ($this->subcategories) return $this->subcategories->count();
...@@ -567,7 +591,12 @@ class Option ...@@ -567,7 +591,12 @@ class Option
*/ */
public function setParent(\Biopen\GeoDirectoryBundle\Document\Category $parent) public function setParent(\Biopen\GeoDirectoryBundle\Document\Category $parent)
{ {
if ($parent && in_array($parent->getId(), $this->getAllSubcategoriesIds())) {
// Circular reference
} else {
$this->parent = $parent; $this->parent = $parent;
}
return $this; return $this;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment