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
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
->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6'))
->add('name', null, array('required' => true, 'label' => 'Nom du groupe'))
......@@ -48,6 +53,7 @@ class CategoryAdmin extends AbstractAdmin
->add('parent', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Option',
'required' => false,
'query' => $parentQuery,
'choices_as_values' => true,
'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"]))
......
......@@ -21,7 +21,7 @@ use Knp\Menu\ItemInterface;
class OptionAdmin extends AbstractAdmin
{
protected $baseRouteName = 'admin_biopen_geodirectory_option';
protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
public function createQuery($context = 'list')
{
......@@ -41,6 +41,11 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
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
->tab('Principal')
->with('Paramètres principaux', array('class' => 'col-xs-12 col-md-6'))
......@@ -50,6 +55,7 @@ protected $baseRoutePattern = 'admin_biopen_geodirectory_option';
->add('parent', 'sonata_type_model', array(
'class'=> 'Biopen\GeoDirectoryBundle\Document\Category',
'required' => true,
'query' => $parentQuery,
'choices_as_values' => true,
'label' => 'Groupe de Catégorie parent',
'mapped' => true), array('admin_code' => 'admin.categories.lite_hidden'))
......
......@@ -184,6 +184,23 @@ class Category
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
*
......@@ -409,11 +426,15 @@ class Category
*/
public function setParent($parent, $updateParent = true)
{
if ($parent && in_array($parent->getId(), $this->getAllOptionsIds())) {
// Circular reference
} else {
// clearing old parent
if ($updateParent && $this->parent) $this->parent->removeSubcategory($this, false);
$this->parent = $parent;
if ($updateParent && $parent) $parent->addSubcategory($this, false);
}
return $this;
}
......
......@@ -192,6 +192,13 @@ class Option
return $this->getName();
}
public function allSubcategories()
{
$result = [];
return $result;
}
public function getNameWithParent()
{
$result = '';
......@@ -245,6 +252,23 @@ class Option
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()
{
if ($this->subcategories) return $this->subcategories->count();
......@@ -567,7 +591,12 @@ class Option
*/
public function setParent(\Biopen\GeoDirectoryBundle\Document\Category $parent)
{
if ($parent && in_array($parent->getId(), $this->getAllSubcategoriesIds())) {
// Circular reference
} else {
$this->parent = $parent;
}
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