簡體   English   中英

如何使用symfony 2.3調用訂戶中的實體管理器類?

[英]How to call entity manager class in subscriber using symfony 2.3?

我想在事件訂閱服務器中調用存儲庫類函數。 3張桌子


桌子


country : id, name, abbr, is_active
city : id, cityname, is_active
countrycity : id,countryid, cityid.

我應該在管理面板中提供管理城市,管理員可以在該國家/地區中添加自己的城市。

對於一個應用程序,我創建了一個commonBundle,所有公共實體都駐留在其中,並將在管理面板和前端中使用。


格式:D:\\ wamp \\ www \\ cl \\ src \\ Cl \\ CommonBundle \\ Form \\ CityType.php


namespace Cl\CommonBundle\Form;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Symfony\Component\Validator\Constraints;
    use Doctrine\ORM\EntityManager;
    class CityType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                    ->add("country", "entity", array("class" => "ClCommonBundle:Country", "property" => "countryname", "empty_value" => "-- Select Country --", "required" => false, "constraints" => new Constraints\NotBlank(array("message" => "Country should not be empty"))))
                    ->add("cityname", "text", array("label" => "Name", "required" => false))
                    ->add("isactive", "checkbox", array("required" => false, "label" => "Is active?", "mapped" => true))

            //->add('createdat')
            //->add('updatedat')
            ;
            $builder->addEventSubscriber(new EventListner\ValidateCountryCitySubscriber());

            /* $builder->addValidator(new CallbackValidator(function(FormInterface $form) {
              $country = $form->get("country")->getData();
              if (!$country) {
              $form['country']->addError(new FormError("Country should not be emtpy"));
              }
              }
              )); */
        }

        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                // "data_class" => "Cl\CommonBundle\Entity\City",
                "csrf_token" => true,
                "csrf_token_name" => "_token",
                "method" => "POST",
                // to generate unique key token per form
                "intention" => "city",
                "country" => true,
                "mapped" => false,
                'allowExtraFields' => true
                    // validation group
                    //"validation_groups" => false,
            ));
        }

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

    }

我創建了事件列表器功能,以在該國家/地區已經存在城市名稱時調用錯誤。

$builder->addEventSubscriber(new EventListner\ValidateCountryCitySubscriber());
    The code of event listiner is following.

EventListner:D:\\ wamp \\ www \\ Cl \\ src \\ Cl \\ CommonBundle \\ Form \\ EventListner \\ ValidateCountryCitySubscriber.php


namespace Cl\CommonBundle\Form\EventListner;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\ManagerRegistry;

class ValidateCountryCitySubscriber implements EventSubscriberInterface
{
    private $em;
    /**
     * @param EntityManager
     */
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }
    public static function getSubscribedEvents()
    {
        return [FormEvents::POST_SUBMIT => 'postSubmit'];
    }
    public function postSubmit(FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();
        $country = $event->getForm()->getData()->country->getId();
        $cityname = $data->getCityname();
        $this->em->getRepository("CommonBundle:CountryCity")->validateCountryCity($country, $city);
        //$form->addError(new FormError("City is already exists for this country"));
    }
}

在D:\\ wamp \\ www \\ Cl \\ app \\ config \\ config.yml中創建服務


doctrine.listner:
class: Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber
arguments:
    - @doctrine.orm.entity_manager

::錯誤::


哎呀,看起來像出事了。

1/1 ContextErrorException: Catchable Fatal Error: Argument 1 passed to Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber::__construct() must be an instance of Cl\CommonBundle\Form\EventListner\EntityManager, none given, called in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\CityType.php on line 27 and defined in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber.php line 20
in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber.php line 20
at ErrorHandler->handle('4096', 'Argument 1 passed to Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber::__construct() must be an instance of Cl\CommonBundle\Form\EventListner\EntityManager, none given, called in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\CityType.php on line 27 and defined', 'D:\wamp\www\Cl\src\Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber.php', '20', array()) in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber.php line 20
at ValidateCountryCitySubscriber->__construct() in D:\wamp\www\Cl\src\Cl\CommonBundle\Form\CityType.php line 27
at CityType->buildForm(object(FormBuilder), array('block_name' => null, 'disabled' => false, 'label' => null, 'attr' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'data_class' => 'Cl\CommonBundle\Entity\City', 'empty_data' => object(Closure), 'trim' => true, 'required' => true, 'read_only' => false, 'max_length' => null, 'pattern' => null, 'property_path' => null, 'mapped' => false, 'by_reference' => true, 'error_bubbling' => true, 'label_attr' => array(), 'virtual' => null, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'validation_groups' => null, 'error_mapping' => array(), 'constraints' => array(), 'cascade_validation' => false, 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'extra_fields_message' => 'This form should not contain extra fields.', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_provider' => object(SessionCsrfProvider), 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'intention' => 'city', 'csrf_token' => true, 'csrf_token_name' => '_token', 'country' => true, 'allowExtraFields' => true, 'action' => '/Cl/web/app_dev.php/admin/city/insert', 'data' => object(City))) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php line 158
at ResolvedFormType->buildForm(object(FormBuilder), array('block_name' => null, 'disabled' => false, 'label' => null, 'attr' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'data_class' => 'Cl\CommonBundle\Entity\City', 'empty_data' => object(Closure), 'trim' => true, 'required' => true, 'read_only' => false, 'max_length' => null, 'pattern' => null, 'property_path' => null, 'mapped' => false, 'by_reference' => true, 'error_bubbling' => true, 'label_attr' => array(), 'virtual' => null, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'validation_groups' => null, 'error_mapping' => array(), 'constraints' => array(), 'cascade_validation' => false, 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'extra_fields_message' => 'This form should not contain extra fields.', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_provider' => object(SessionCsrfProvider), 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'intention' => 'city', 'csrf_token' => true, 'csrf_token_name' => '_token', 'country' => true, 'allowExtraFields' => true, 'action' => '/Cl/web/app_dev.php/admin/city/insert', 'data' => object(City))) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Component\Form\ResolvedFormType.php line 117
at ResolvedFormType->createBuilder(object(FormFactory), 'Cl_commonbundle_city', array('action' => '/Cl/web/app_dev.php/admin/city/insert', 'data' => object(City))) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Component\Form\FormFactory.php line 87
at FormFactory->createNamedBuilder('Cl_commonbundle_city', object(CityType), object(City), array('action' => '/Cl/web/app_dev.php/admin/city/insert')) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Component\Form\FormFactory.php line 67
at FormFactory->createBuilder(object(CityType), object(City), array('action' => '/Cl/web/app_dev.php/admin/city/insert')) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Component\Form\FormFactory.php line 39
at FormFactory->create(object(CityType), object(City), array('action' => '/Cl/web/app_dev.php/admin/city/insert')) in D:\wamp\www\Cl\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Controller\Controller.php line 163
at Controller->createForm(object(CityType), object(City), array('action' => '/Cl/web/app_dev.php/admin/city/insert')) in D:\wamp\www\Cl\src\Cl\AdminBundle\Controller\CityController.php line 19
at CityController->__processForm(array('entity' => object(City), 'path' => '_admin_city_insert', 'button_label' => 'Add')) in D:\wamp\www\Cl\src\Cl\AdminBundle\Controller\CityController.php line 38
at CityController->addAction(object(Request))
at call_user_func_array(array(object(CityController), 'addAction'), array(object(Request))) in D:\wamp\www\Cl\app\bootstrap.php.cache line 2889
at HttpKernel->handleRaw(object(Request), '1') in D:\wamp\www\Cl\app\bootstrap.php.cache line 2863
at HttpKernel->handle(object(Request), '1', true) in D:\wamp\www\Cl\app\bootstrap.php.cache line 2992
at ContainerAwareHttpKernel->handle(object(Request), '1', true) in D:\wamp\www\Cl\app\bootstrap.php.cache line 2272
at Kernel->handle(object(Request)) in D:\wamp\www\Cl\web\app_dev.php line 28

您沒有指定EntityManager來自哪個名稱空間。

因此,只需添加use Doctrine\\ORM\\EntityManager; 在您的訂戶中:

namespace Cl\CommonBundle\Form\EventListner;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormError;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\ManagerRegistry;
use Doctrine\ORM\EntityManager; // this was lacking

class ValidateCountryCitySubscriber implements EventSubscriberInterface
{

編輯:

好的,我現在知道問題出在哪里。

您將訂戶創建為服務,但是在類型類中,您並未將其用作服務,而是自己創建了新對象。 這是一個錯誤,您應該使用容器來管理依賴項。 請嘗試以下方式:

  1. CityType定義為服務
  2. 將訂戶注入CityType並使用此注入的對象

編輯2:

問題是由於此行:

$builder->addEventSubscriber(new EventListner\ValidateCountryCitySubscriber());

您創建了新的訂閱者對象,但從未傳遞EntityManager依賴項。 但是您已經將訂戶定義為服務: doctrine.listner 因此,您唯一要做的就是將其注入CityType類中。

為此,您需要將CityType定義為服務:

form.type.city:
    class: Cl\CommonBundle\Form\CityType
    arguments: [ @doctrine.listner ]
    tags:
        - { name: form.type, alias: city_type }

當然,您需要稍微修改CityType (創建構造函數,在其中注入ValidateCountryCitySubscriber類和$doctrineListener屬性):

protected $doctrineListener

public function __construct(ValidateCountryCitySubscriber $doctrineListener)
{
    $this->doctrineListener = $doctrineListener;
}

然后在類型類內部,以這種方式添加訂戶:

$builder->addEventSubscriber($this->doctrineListener);

兩個錯誤:

1-正如Cyprian所說,您應該讓ValidateCountryCitySubscriber知道在哪里可以找到EntityManager

因此必須use Doctrine\\ORM\\EntityManager包含在ValidateCountryCitySubscriber類的使用定義中

2-您應該將 config.yml修改為

 
 
 
  
  doctrine.listner: class: Cl\\CommonBundle\\Form\\EventListner\\ValidateCountryCitySubscriber arguments: [ @doctrine.orm.entity_manager ]
 
  

另外你的語法似乎很好

編輯

問題也出現在您的FormType :您不應使服務的身份無效(而ValidateCountryCitySubscriber就是)。 因此您可以通過這種方式修改config.yml

yourbundle.citytype:
    class: Cl\CommonBundle\Form\CityType
    arguments: [ @doctrine.listner ]
    tags:
        - { name: form.type, alias: Cl_commonbundle_city }

您正在將doctrine.listner服務注入到表單中(現在也是一種服務)。

比修改CityType

use Cl\CommonBundle\Form\EventListner\ValidateCountryCitySubscriber.php;
class CityType extends AbstractType
{
    private $vccs; //validate country city subscriber

    public function __construct(ValidateCountryCitySubscriber $validate_country_city_sub)
    {
        $this->vccs = $validate_country_city_sub;
    }  

    [...]

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        [...]
        $builder->addEventSubscriber($this->vccs);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM