Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Как организовать динамические списки категорий и субкатегорий с применением форм в Symfony2?

Anna | 31.05.2014 | нет комментариев

Сотрудники, столкнулся с маленький задачкой, решение для которой никак не обнаружу. Поучаствуйте в мозговом штурме, может кто-то встречал схожую задачу.

Я использую Symfony2.3. Мы имеем, Entity:

Category:

    // src/Acme/DemoBundle/Entity/Category.php

    namespace AcmeDemoBundleEntity;

    use GedmoMappingAnnotation as Gedmo;
    use DoctrineORMMapping as ORM;

    /**
     * @GedmoTree(type="nested")
     * @ORMTable(name="categories")
     * use repository for handy tree functions
     * @ORMEntity(repositoryClass="GedmoTreeEntityRepositoryNestedTreeRepository")
     */
    class Category
    {
        /**
         * @ORMColumn(name="id", type="integer")
         * @ORMId
         * @ORMGeneratedValue
         */
        private $id;

        /**
         * @GedmoTranslatable
         * @ORMColumn(name="name", type="string", length=64)
         */
        private $name;

        /**
         * @GedmoTreeLeft
         * @ORMColumn(name="lft", type="integer")
         */
        private $lft;

        /**
         * @GedmoTreeLevel
         * @ORMColumn(name="lvl", type="integer")
         */
        private $lvl;

        /**
         * @GedmoTreeRight
         * @ORMColumn(name="rgt", type="integer")
         */
        private $rgt;

        /**
         * @GedmoTreeRoot
         * @ORMColumn(name="root", type="integer", nullable=true)
         */
        private $root;

        /**
         * @GedmoTreeParent
         * @ORMManyToOne(targetEntity="Category", inversedBy="children")
         * @ORMJoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
         */
        private $parent;

        /**
         * @ORMOneToMany(targetEntity="Category", mappedBy="parent")
         * @ORMOrderBy({"lft" = "ASC"})
         */
        private $children;

Item:

// src/Acme/DemoBundle/Entity/Item.php
    namespace AcmeDemoBundleEntity;

    use DoctrineExtensionsTaggableTaggable;
    use DoctrineCommonCollectionsArrayCollection;
    use DoctrineORMMapping as ORM;
    use DoctrineCommonCollectionsCollection;

    /**
     * Item entity
     *
     * @ORMTable(name="items")
     * @ORMHasLifecycleCallbacks
     * @ORMEntity
     */
    class Item implements Taggable
    {
        /**
         * @ORMId
         * @ORMColumn(type="integer")
         * @ORMGeneratedValue(strategy="AUTO")
         */
        protected $id;

        /**
         * @ORMColumn(name="name", type="string", length=64, nullable=true)
         */
        protected $name;

        /**
         * @ORMManyToMany(targetEntity="Category", inversedBy="items")
         * @ORMJoinColumn(name="category_id", referencedColumnName="id"),
         *      inverseJoinColumn=(name="item_id", referencedColumnName="id")
         *
         **/
        protected $categories;

         public function getCategories(){
            return $this->categories;
        }

        public function setCategories($categories){
            $this->categories = $categories;

            return $this->categories;
        }

Помимо этого, у нас есть тип формы:
AddItemForm:

    // src/Acme/DemoBundle/Form/AddItemForm.php
    namespace AcmeDemoBundleForm;

    use SymfonyComponentFormAbstractType;
    use SymfonyComponentFormFormBuilderInterface;
    use SymfonyComponentOptionsResolverOptionsResolverInterface;
    use DoctrineORMEntityRepository;
    use SymfonyComponentValidatorConstraintsCollection;

    /**
     * Add item form
     *
     */
    class AddModelForm extends AbstractType
    {    public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder->add('categories', 'collection', array(
                                                            'type' => 'entity',
                                                            'allow_add' => true,
                                                            'allow_delete' => true,
                                                            'prototype' => true,
                                                            'show_legend' => false,
                                                            'data' => array(''),
                                                            'widget_add_btn' => array('label' => _('Добавить категорию')),
                                                            'options' => array(
                                                                            'widget_control_group' => false,
                                                                            'label_render' => false,
                                                                            'class' => 'AcmeDemoBundle:Category',
                                                                            'query_builder' => function(EntityRepository $er) {
                                                                                return $er->createQueryBuilder('c')
                                                                                    ->where('c.lvl = 0')
->orderBy('c.id', 'ASC');
                                                                            },
                                                                            'property' => 'name',
                                                                            'empty_value' => _('Choose category'),
                                                                        ),

                                                        )
                                  );
        }
    }

И контроллер ItemController:

   // src/Acme/DemoBundle/Controller/ItemController.php
    ...
    public function editAction($itemId) {
        $item= $em->getRepository('AcmeDemoBundle:Item')
                      ->findOneById($itemId);

        $form = $this->createForm(new AddItemForm(), $item);
    }

    public function addAction() {
        $item = new Item();

        $form = $this->createForm(new AddItemForm(), $item);
    }
    ...

Категории содержат подкатегории, которые, в свою очередь, тоже содержат подкатегории и т.д. Реализация nested tree из doctrine extensions.
Что я хочу получить?:

1) Когда я добавляю новейший предмет и перехожу к выбору категорий, к которым он принадлежит, я хочу получить следующее повидение (скриншот мой, на английском): вид выбора категорий.

Т.е. я выбираю категорию, подкатегорию и т.д. до момента, когда у категории не будет потомков (скажем: Оружие-Магическое-Посохи). 1-я категория, к которой принадлежит предмет — Посохи. Дозволено добавить до N категорий. Нажминая «добавить категорию», возникает выпадающий список нулевого яруса и динамическое возникновение подкатегорий происходит как было описано ранее.

2) Когда я редактирую предмет, я жду увидеть теснее раскрытые категории до последней, с вероятностью редактировать их.

Безусловно, я могу реализовать это с поддержкой javascript, в контроллере получить список категорий, путь до корня всякой и в twig образце рендерить это дело. Но хотелось бы обнаружить best practice решение.

Скоре каждого я что-то упустил, т.к. компонент в Form в Symfony2 довольно обширный. Может, необходимое поведение в моем случае может подмогнуть организовать какой-либо Bundle? Но вновь же, пока, я ничего не обнаружил.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB