选择与当前商店实体相关的类别

时间:2014-08-02 17:54:16

标签: php symfony doctrine-orm

我有两个实体商店类别,每个商店都有自己的类别。 我希望当商店所有者尝试添加新类别和category_parent时,只会显示与当前商店相关的类别。

现在,所有类别都显示在select-option中。 我使用Tree Gedmo扩展来管理Category实体,并使用 getChildrenQueryBuilder 方法来选择类别。

如何修改此方法并添加我的特定约束?

$ store 这是在控制器操作中声明的约束。

我在尝试添加 category_parent 时禁用了设置当前类别选项,因此类别和类别父级必须不同。

我希望它清楚

CategoryType.php

<?php

namespace Project\StoreBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;

class CategoryType extends AbstractType
{
    /**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        //..........
        //..........
        ->add('category', 'entity', array(
        'required' => false,
        'label' => 'Category parent',
        'class' => 'ProjectStoreBundle:Category',
        'attr' => array('class' => 'col-sm-8'),
        'empty_value' => 'Select one category',
        'property' => 'indentedName',
        'multiple' => false,
        'expanded' => false ,
        'query_builder' => function (\Project\StoreBundle\Entity\CategoryRepository $r)
            {
                return $r->getChildrenQueryBuilder(null, null, 'root', 'asc', false);
            }
        ))
    ;
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Project\StoreBundle\Entity\Category'
    ));
}

/**
 * @return string
 */
public function getName()
{
    return 'project_storebundle_category';
}
}

实体/ Category.php

<?php

namespace Project\StoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;


use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;


/**
* Category
* @Gedmo\Tree(type="nested")
* @ORM\Table()
* @ORM\Entity(repositoryClass="Project\StoreBundle\Entity\CategoryRepository")
* @ORM\HasLifeCycleCallbacks()
*/
class Category
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 *
 *@Assert\NotBlank(message="Please enter the name of categorie.")
 */
private $name;

/**
 * @Gedmo\slug(fields={"name"}, unique_base="uniqueBase")
 * @ORM\Column(name="slug",length=255, unique=false)
 */
private $slug ;

/**
 * @ORM\Column(name="uniqueBase", type="integer")
 */
private $uniqueBase ;

/**
 * @ORM\Column(name="description", type="text", nullable=true)
 */
private $description;

/**
 * @ORM\Column(name="metaDescription", type="string", length=255, nullable=true)
 *
 * @Assert\Length(
 *     max=255,
 *     maxMessage="message"
 *  )
 */
private $metaDescription;

/**
 * @ORM\Column(name="metaKeywords", type="string", length=255, nullable=true)
 *
 * @Assert\Length(
 *     max=255,
 *     maxMessage="message"
 *  )
 */
private $metaKeywords;


/**
 * @ORM\Column(name="enabled", type="boolean", nullable=false)
 */
private $enabled;


/**
 * @Gedmo\TreeLeft
 * @ORM\Column(name="lft", type="integer")
 */
private $lft;

/**
 * @Gedmo\TreeLevel
 * @ORM\Column(name="lvl", type="integer")
 */
private $lvl;

/**
 * @Gedmo\TreeRight
 * @ORM\Column(name="rgt", type="integer")
 */
private $rgt;

/**
 * @Gedmo\TreeRoot
 * @ORM\Column(name="root", type="integer", nullable=true)
 */
private $root;

/**
 * @Gedmo\TreeParent
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
 */
private $parent;

/**
 * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
 * @ORM\OrderBy({"lft" = "ASC"})
 */
private $children;

/**
 *non mapped property 
 */
private $indentedName;

/**
 *non mapped property 
 */
private $category;

/**
 * @ORM\ManyToOne(targetEntity="Project\StoreBundle\Entity\Store", inversedBy="categories", cascade={"persist"})
 * @ORM\JoinColumn(nullable=false)
 */
private $store ;


/**
 * Constructor
 */
public function __construct()
{
    $this->children = new ArrayCollection();
}


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 * @return Category
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}

/**
 * Set slug
 *
 * @param string $slug
 * @return Category
 */
public function setSlug($slug)
{
    $this->slug = $slug;

    return $this;
}

/**
 * Get slug
 *
 * @return string 
 */
public function getSlug()
{
    return $this->slug;
}

/**
 * Set uniqueBase
 *
 * @param integer $uniqueBase
 * @return Category
 */
public function setUniqueBase($uniqueBase)
{
    $this->uniqueBase = $uniqueBase;

    return $this;
}

/**
 * Get uniqueBase
 *
 * @return integer 
 */
public function getUniqueBase()
{
    return $this->uniqueBase;
}

/**
 * Set description
 *
 * @param string $description
 * @return Category
 */
public function setDescription($description)
{
    $this->description = $description;

    return $this;
}

/**
 * Get description
 *
 * @return string 
 */
public function getDescription()
{
    return $this->description;
}

/**
 * Set metaDescription
 *
 * @param string $metaDescription
 * @return Category
 */
public function setMetaDescription($metaDescription)
{
    $this->metaDescription = $metaDescription;

    return $this;
}

/**
 * Get metaDescription
 *
 * @return string 
 */
public function getMetaDescription()
{
    return $this->metaDescription;
}

/**
 * Set metaKeywords
 *
 * @param string $metaKeywords
 * @return Category
 */
public function setMetaKeywords($metaKeywords)
{
    $this->metaKeywords = $metaKeywords;

    return $this;
}

/**
 * Get metaKeywords
 *
 * @return string 
 */
public function getMetaKeywords()
{
    return $this->metaKeywords;
}

/**
 * Set enabled
 *
 * @param boolean $enabled
 * @return Category
 */
public function setEnabled($enabled)
{
    $this->enabled = $enabled;

    return $this;
}

/**
 * Get enabled
 *
 * @return boolean 
 */
public function getEnabled()
{
    return $this->enabled;
}

/**
 * Set parent
 *
 * @param \Project\StoreBundle\Entity\Category $parent
 * @return Category
 */
public function setParent(\Project\StoreBundle\Entity\Category $parent = null)
{
    $this->parent = $parent;

    return $this;
}

/**
 * Get parent
 *
 * @return \Project\StoreBundle\Entity\Category 
 */
public function getParent()
{
    return $this->parent;
}

/**
 * Set lft
 *
 * @param integer $lft
 * @return Category
 */
public function setLft($lft)
{
    $this->lft = $lft;

    return $this;
}

/**
 * Get lft
 *
 * @return integer 
 */
public function getLft()
{
    return $this->lft;
}

/**
 * Set lvl
 *
 * @param integer $lvl
 * @return Category
 */
public function setLvl($lvl)
{
    $this->lvl = $lvl;

    return $this;
}

/**
 * Get lvl
 *
 * @return integer 
 */
public function getLvl()
{
    return $this->lvl;
}

/**
 * Set rgt
 *
 * @param integer $rgt
 * @return Category
 */
public function setRgt($rgt)
{
    $this->rgt = $rgt;

    return $this;
}

/**
 * Get rgt
 *
 * @return integer 
 */
public function getRgt()
{
    return $this->rgt;
}

/**
 * Set root
 *
 * @param integer $root
 * @return Category
 */
public function setRoot($root)
{
    $this->root = $root;

    return $this;
}

/**
 * Get root
 *
 * @return integer 
 */
public function getRoot()
{
    return $this->root;
}

/**
 * Add children
 *
 * @param \Project\StoreBundle\Entity\Category $children
 * @return Category
 */
public function addChild(\Project\StoreBundle\Entity\Category $children)
{
    $this->children[] = $children;

    return $this;
}

/**
 * Remove children
 *
 * @param \Project\StoreBundle\Entity\Category $children
 */
public function removeChild(\Project\StoreBundle\Entity\Category $children)
{
    $this->children->removeElement($children);
}

/**
 * Get children
 *
 * @return \Doctrine\Common\Collections\Collection 
 */
public function getChildren()
{
    return $this->children;
}

/**
 * Get IndentedName
 *
 */
public function getIndentedName()
{
    return str_repeat("-----", $this->lvl).$this->name;
}

/**
 * Get category
 *
 */
public function getCategory()
{
    return $this->category;
}

/**
 * Set store
 *
 * @param \Project\StoreBundle\Entity\Store $store
 * @return Category
 */
public function setStore(\Project\StoreBundle\Entity\Store $store = null)
{
    $this->store = $store;

    return $this;
}

/**
 * Get store
 *
 * @return \Project\StoreBundle\Entity\Store 
 */
public function getStore()
{
    return $this->store;
}

}

控制器

    /**
 * Create a new Category entity.
 *
 */
/**
* @ParamConverter("store", options={"mapping": {"store_id":"id"}})
*/
public function newAction(Store $store)
{
    // keep in mind, this will call all registered security voters
    if (false === $this->get('security.context')->isGranted('edit', $store)) {
        throw new AccessDeniedException('Unauthorised access!');
    }       

    $category = new Category();
    $category->setStore($store);
    $category->setUniqueBase($store->getId());

    $form = $this->createForm(new CategoryType(), $category);

    $request = $this->getRequest();

    if ($request->getMethod() == 'POST')
    {
        $form->bind($request);

        if ($form->isValid())
        {
            $em = $this->getDoctrine()->getManager();   
            $em->persist($category);
            $em->flush();

            $this->get('session')->getFlashBag()->add('message', 'Category enregistred');

            return $this->redirect( $this->generateUrl('dashboard_category_index', array('store_id' => $store->getId())));
        }
    }

    return $this->render('ProjectDashboardBundle:Category:new.html.twig',
    array(
        'form' => $form->createView() ,
        'store' =>$store,
        ));
}

我设法将参数 $ store 传递给表单,但我不知道如何将其用作 getChildrenQueryBuilder 方法中的约束。 我应该创建一个新的自定义方法吗?如果可能的话,我更喜欢使用 getChildrenQueryBuilder

这是新代码

CategoryType.php

class CategoryType extends AbstractType
{

private $store;

public function __construct($store)
{
    $this->store = $store;
}
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $store = $this->store;

    $builder
        //...........
        //...........

        ->add('parent', 'entity', array(
        'required' => false,
        'label' => 'Category parent',
        'class' => 'ProjectStoreBundle:Category',
        'attr' => array('class' => 'col-sm-8'),
        'empty_value' => 'Select one category',
        'property' => 'indentedName',
        'multiple' => false,
        'expanded' => false ,
        'query_builder' => function (\Project\StoreBundle\Entity\CategoryRepository $r) use ($store)
            {
                return $r->getChildrenQueryBuilder(null, null, 'root', 'asc', false);
            }
        ))
    ;
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Project\StoreBundle\Entity\Category'
    ));
}

/**
 * @return string
 */
public function getName()
{
    return 'project_storebundle_category';
}
}

控制器

/**
* @ParamConverter("store", options={"mapping": {"store_id":"id"}})
*/
public function newAction(Store $store)
{
    // keep in mind, this will call all registered security voters
    if (false === $this->get('security.context')->isGranted('edit', $store)) {
        throw new AccessDeniedException('Unauthorised access!');
    }       

    $category = new Category();
    $category->setStore($store);
    $category->setUniqueBase($store->getId());

    $form = $this->createForm(new CategoryType($store), $category);

    $request = $this->getRequest();

    if ($request->getMethod() == 'POST')
    {
        $form->bind($request);

        if ($form->isValid())
        {
            $em = $this->getDoctrine()->getManager();   
            $em->persist($category);
            $em->flush();

            $this->get('session')->getFlashBag()->add('message', 'Category  enregistred');

            return $this->redirect( $this->generateUrl('dashboard_category_index', array('store_id' => $store->getId())));
        }
    }

    return $this->render('ProjectDashboardBundle:Category:new.html.twig',
    array(
        'form' => $form->createView() ,
        'store' =>$store,
        ));
}

1 个答案:

答案 0 :(得分:0)

您并未说明您正在使用哪个Symfony2版本,但一般来说,您只需要找到一种方法将当前商店传递给表单构建器并在过滤可能的方法中使用它类别。

看一下this onethis one,基本上你只需要将$ store注入你的表单构建器,然后你(几乎)拥有它: - )