Symfony2 - Как реализовать вложенные записи и рекурсивные функции в Entity Field или Twig Layout? - PullRequest
4 голосов
/ 02 февраля 2012

У меня есть серьезные сомнения по поводу создания комбинированного списка с вложенными записями от сущности в Symfony2. Я прочитал о расширении вложенного дерева для Doctrine 2 в http://gediminasm.org/article/tree-nestedset-behavior-extension-for-doctrine-2,, это кажется интересным, но в нем не говорится, как реализовать это вложенное дерево в поле сущности в форме.

Кроме того, я прочитал больше о рекурсивных функциях в PHP, и я нашел интересный блог, где он анализируется, вот ссылка http://www.sitepoint.com/hierarchical-data-database/,, в которой конкретно объясняется эта рекурсивная функция:

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);
    }
}

Кто-то знает, как перевести этот код в Symfony2 и где он будет храниться (Controller, Entity и т. Д.). Если у кого-то есть другие идеи по поводу работы с вложенными записями с помощью Twig Extensions, было бы очень полезно.

Большое спасибо за помощь.

Ответы [ 2 ]

7 голосов
/ 09 июля 2012

Вот как мы реализовали вложенное дерево для категорий (раскрывающийся список с отступом) для использования в форме редактирования продукта:

  1. Определите свой класс сущности категории, как показано в документации

  2. Добавить метод к классу сущностей Category, который отображает имя с отступом от уровня вложенности

    /**
     * @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();
        }
    
  3. Определить отношения сущностей Product сОбъекты категорий, использующие аннотации Doctrine2 (в нашем случае у нас есть поддержка нескольких категорий для одного продукта)

    class Product
    {
        /**
         * @var ArrayCollection
         * @ORM\ManyToMany(targetEntity="Category", cascade={"persist", "remove"})
         */
        private $categories;
        ...
    
  4. Теперь все, что вам нужно сделать, это добавить следующее в класс формы ProductType

    class ProductType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
            $builder
                ->add('categories', null, array('property' => 'optionLabel'));
        }
    

Теперь в форме должен отображаться выпадающий список с правильно выделенным списком категорий

2 голосов
/ 02 февраля 2012

Вы можете взглянуть на эту реализацию дерева, которая основана не на вложенных наборах, а на материализованных путях: https://github.com/KnpLabs/materialized-path.

Вы можете использовать его API, чтобы получить плоский набор результатов дерева, как в вашем фрагменте кода:

$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);
...