-
-
Save mdzzohrabi/784034549f2217badf96e844df2792e5 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* (c) Masoud Zohrabi <[email protected]> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace Mdzzohrabi\Form; | |
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\ChoiceList\View\ChoiceView; | |
use Symfony\Component\Form\FormInterface; | |
use Symfony\Component\Form\FormView; | |
use Symfony\Component\OptionsResolver\OptionsResolver; | |
/** | |
* Class EntityTreeType | |
* @package Mdzzohrabi\Form | |
*/ | |
class EntityTreeType extends AbstractType { | |
public function buildView( FormView $view , FormInterface $form , array $options ) { | |
$choices = []; | |
foreach ( $view->vars['choices'] as $choice ) { | |
if ( $choice->data->getParent() === null ) | |
$choices[ $choice->value ] = $choice->data; | |
} | |
$choices = $this->buildTreeChoices( $choices ); | |
$view->vars['choices'] = $choices; | |
} | |
/** | |
* @param object[] $choices | |
* @param int $level | |
* @return array | |
*/ | |
protected function buildTreeChoices( $choices , $level = 0 ) { | |
$result = array(); | |
foreach ( $choices as $choice ){ | |
$result[ $choice->getId() ] = new ChoiceView( | |
$choice, | |
(string)$choice->getId(), | |
str_repeat( '--' , $level ) . ' ' . $choice->getName(), | |
[] | |
); | |
if ( !$choice->getChilds()->isEmpty() ) | |
$result = array_merge( | |
$result, | |
$this->buildTreeChoices( $choice->getChilds() , $level + 1 ) | |
); | |
} | |
return $result; | |
} | |
public function getParent() { | |
return EntityType::class; | |
} | |
} |
@teemuparkkinen Doctrine Query builder only apply conditions on root nodes , you must customize your getChilds()
methods in your Entity Class or create a new method for get childs and use updated version of EntityTreeType
class by @kl3sk and pass you customized get childs methods name into 'children_method_name'
option.
myCustomParentFunctionName and myCustomChildrenFunctionName are both supposed to return a string ?
I have an error Object of class App\Entity\Theme could not be converted to string
.
My getParent and getChildren method returns objects (and a collection for the getChildren) and I don't know how to do.
Any tips ?
Edit: My bad, noob error... I added the __toString() method and it worked. I also used the last version of kl3sk's fork (for the entity_method_name option)
@tony5Dim implement __toString() method in your entity that return the name for example.
Edit : sorry I didn’t see that you’ve ever made that ^^
FIX BUG
$result = array_merge(
$result,
[new ChoiceView(
$choice,
(string)$choice->getId(),
str_repeat($options['prefix'], $level) . ' ' . $choice->getName(),
[]
)]
);
if (!$choice->$children_method_name()->isEmpty())
$result = array_merge(
$result,
$this->buildTreeChoices($choice->$children_method_name(), $options, $level + 1)
);
Hello!
Thank you for share this code!
It works fine when "multiple" and "expanded" are false, but:
'multiple' => true,
'expanded' => true,
Choices generated by this class are overridden by original EntityType class, losing hierarchy and order.
How can we do?
Thank you!
Is it possible to use query_builder with this?
This is not working. It shows all choices even if I don't search all in the query.
->add('category', EntityTreeType::class, [ 'class' => Category::class, 'query_builder' => ...