Symfony2 /在formType中使用自定义存储库方法

时间:2012-05-04 05:40:36

标签: symfony repository

我是Symfony2的新手,希望我足够清楚。

我有一个存储库:

class districtRepository extends EntityRepository
{
     public function findAllFromCity($idCity)
    {


            return $this->createQueryBuilder('d')
                        ->where('d.city = :city')
                        ->setParameter('city', $idCity)
                        ->orderBy('d.name', 'ASC');
                        ->getQuery()
                        ->getResult();

    }
}

表单类型

class searchPropertyType extends AbstractType
{

    public function getDefaultOptions(array $options)
    {
        // return array('validation_constraint' => $collectionConstraint
       return array ('required'=>false, 'csrf_protection' => true); 
    }


    public function buildForm(FormBuilder $builder, array $options)
    {

        $em = $this->getDoctrine()->getEntityManager();

        $builder
            ->add('keywords')
            ->add('disctrict')    
            ->add('price_min')
            ->add('price_max')
            ->add('type')                                             
            ->add('date_from' , 'date', array('widget' => 'single_text'))
            ->add('date_to' , 'date', array('widget' => 'single_text'))
        ;


    }

    public function getName()
    {
        return 'searchProperty';
    }
}

如何使用findAllFromCity()获取->add('disctrict')中的选项列表?

我知道查询生成器解决方案,但它让我重复我的代码。

我已经阅读了有关服务容器解决方案的信息。是适用于我的情况?你能告诉我如何或让我走上好路吗?

3 个答案:

答案 0 :(得分:4)

  1. 事实上,只有在'searchPropertyType'类中访问'findAllFromCity'方法的方法是注入Doctrine注册表。

    在表单类型中:

    use Symfony\Bridge\Doctrine\RegistryInterface;
    
    class searchPropertyType extends AbstractType
    {
        private $doctrine;
    
        public function __construct(RegistryInterface $doctrine)
        {
            $this->doctrine = $doctrine;
        }
    

    在services.xml文件中:

    <service id="my_project.form.type.search_property" class="{mynamespace}\searchPropertyType" public="false">
        <tag name="form.type" />
        <argument type="service" id="doctrine" />
    </service>
    
  2. 为了使用此方法,您必须使用'choices'类型和'choices'或'choice_list'选项。

    在表单类型中:

    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            // ...
            ->add('disctrict', 'choice', $this->getDistrictChoices($options['city_id']))
            // ...
        ;
    }
    
    private function getDistrictChoices()
    {
        $choices = array();
        $districts = $this->doctrine->getRepository('MyBundle:District')->findAllFromCity($cityId);
    
        foreach ($dictricts as $dictrict) {
            $choices[$district->getId()] = $district->getName();
        }
    
        return $choices;
    }
    
  3. 当然,这是一个例子,需要进行调整。 请记住:类名fisrt字母总是大写。

答案 1 :(得分:3)

感谢Simon,我已经更新如下,现在正在运作!

<强> searchController:

public function basicsearchAction(Request $request)
{   
    $form = $this->createForm(new searchPropertyType($this->getDoctrine()));

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

}

<强> searchPropertyType

public function buildForm(FormBuilder $builder, array $options)
    {

        $builder
            ->add('keywords')
            ->add('district', 'choice', array('choices'=>$this->getDistrictChoices(), 'multiple'=>true) )     
            ->add('price_min')
            ->add('price_max')
            ->add('type', 'entity', array('class'=>'FlatShanghaidefaultBundle:propertytype', 
                                          'property'=>'name', 
                                          'multiple'=>true              

                ))


            ->add('date_from' , 'date', array('widget' => 'single_text'))
            ->add('date_to' , 'date', array('widget' => 'single_text'))
        ;


    }

    private function getDistrictChoices()
{
    $choices = array();
    $districts = $this->doctrine->getRepository('FlatShanghaidefaultBundle:district')->findByDefaultCity();

    foreach ($districts as $district) {
        $choices[$district->getId()] = $district->getName();
    }


    return $choices;
}

<强> service.yml

services:
    search_property:
        class:        FlatShanghai\propertyBundle\Form\searchPropertyType
        arguments:    [doctrine]

答案 2 :(得分:0)

我还担心重复的代码。不仅适用于我的查询构建器,而且还不想编写自定义选项映射,例如&#34; getDistrictChoices&#34;。我选择在我的EntityRepository中抽象我的查询,以使其在我的表单类型中也可用。

这就是我的所作所为。

我的表格:

class UserEditType extends AbstractType
{

    /**
     * @var Session $session
     */
    private $session;

    public function __construct(Session $session){
        $this->session = $session;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('firstName')
            ->add('middleName')
            ->add('lastName')
            ->add('username')
            ->add('userStatus', EntityType::class, [
                'class' => UserStatus::class,
                'property' => 'status',
                'query_builder' => function(UserStatusRepository $er) {
                    return $er->createQueryBuilder('s')
                        ->orderBy('s.status');
                },
            ])
            ->add('agency', EntityType::class, [
                'class' => WorkflowGroup::class,
                'property' => 'groupName',
                'query_builder' => function(WorkflowGroupRepository $er) {
                    return $er->createSelectAllQB($this->session->get(AbstractController::SESSION_KEY_AGENCY_ID));
                },
            ])
            ->add('phoneNumber')
            ->add('email', EmailType::class)
            ->add('activationDate', DateType::class, [
                'widget' => 'single_text',
                'format' => 'M/d/yyyy',
                'attr' => [
                    'data-provide' => 'datepicker',
                    'data-date-format' => 'mm/dd/yyyy',
                    'data-date-show-on-focus' => 'false',
                    'data-date-auto-format' => 'true'
                ]
            ])
            ->add('expirationDate', DateTimeType::class, [ 'widget' => 'single_text', 'format' => 'yyyy-MM-dd HH:mm' ]);
        ;
    }
...
}

我的存储库:

class WorkflowGroupRepository extends EntityRepository
{
    public function createSelectAllQB($agencyId)
    {
        return $this->createQueryBuilder('w')
            ->addOrderBy('w.groupName', 'ASC')
            ->andWhere('w.agencyId = :agencyId')
            ->setParameter('agencyId', $agencyId);
    }

    public function selectAll($agencyId)
    {
        return $this->createSelectAllQB($agencyId)->getQuery()->execute();
    }
}
相关问题