[英]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
{
編輯:
好的,我現在知道問題出在哪里。
您將訂戶創建為服務,但是在類型類中,您並未將其用作服務,而是自己創建了新對象。 這是一個錯誤,您應該使用容器來管理依賴項。 請嘗試以下方式:
CityType
定義為服務 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.