I have a serious doubt about doing a combo box with nested records from an entity in Symfony2. I have read about nested tree extension for Doctrine 2 in http://gediminasm.org/article/tree-nestedset-behavior-extension-for-doctrine-2, it appears to be interesting but it does not refer how to implementing this nested tree into an entity field in a form.
Also, I have read more about recursive functions in PHP, and I have found an interesting blog where it is analyzed, here is the link http://www.sitepoint.com/hierarchical-data-database/, it explains specifically about this recursive function:
function display_children($parent, $level) {
// Retrieve all children of $parent
$result = mysql_query('SELECT title FROM tree WHERE parent="'.$parent.'"');
// Display each child
while ($row = mysql_fetch_array($result)) {
// Indent and display the title of this child
echo str_repeat(' ',$level).$row['title']."\n";
// Call this function again to display this child's children
display_children($row['title'], $level+1);
}
}
Somebody knows how to translate this code into Symfony2 and where it would be stored (Controller, Entity, etc.). If someone has other ideas about working nested records with Twig Extensions, It would be appreciate too.
Thanks a lot your help.
This is how we implemented Nested tree for Categories (indented dropdown) for use in Product edit form:
Define your Category entity class as shown in the documentation
Add a method to the Category entity class that shows the name indented by nesting level
/**
* @ORM\Table()
* @ORM\Entity(repositoryClass="CP\YourBundle\Entity\CategoryRepository")
* @Gedmo\Tree(type="nested")
*/
class Category
{
public function getOptionLabel()
{
return str_repeat(
html_entity_decode(' ', ENT_QUOTES, 'UTF-8'),
($this->getLevel() + 1) * 3
) . $this->getName();
}
Define Product entity relations with the Category entities using Doctrine2 annotations (in our case we have multiple categories support for one product)
class Product
{
/**
* @var ArrayCollection
* @ORM\ManyToMany(targetEntity="Category", cascade={"persist", "remove"})
*/
private $categories;
...
Now all you have to do is add the following to the ProductType form class
class ProductType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('categories', null, array('property' => 'optionLabel'));
}
Now the form should show the dropdown with a correctly indented Category list
You can have a look to this tree implementation that is not based on nested sets but on materialzed paths: https://github.com/KnpLabs/materialized-path .
You could imagine use its API to get a flat resultset of the tree, like in your code snippet:
$root = $repo->find($id);
$repo->buildTree($root);
$flatArray = $root->toFlatArray(function(NodeInterface $node) {
$pre = $node->getLevel() > 1 ? implode('', array_fill(0, $node->getLevel(), '--')) : '';
return $pre.(string)$node;
});
return $this->get('templating')->render('::tree.html.twig', $flatArray);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With