我遇到的问题是为Form加载了InputFilters,但不用于验证数据.所有输入都被接受为有效.
例如.我有一个具有名称属性的国家/地区实体.国家/地区的名称必须至少为3个字符且最多为255个.当名称为“ab”时,它被认为是有效的.
在有人问:没有抛出错误之前,数据被接受为有效.
在过去的几天里,我一直在试图找到我犯了错误的地方但是找不到它.
此外,还有相当多的代码.我将它限制在我认为相关的内容中,但是:如果你需要更多,那么会有更多.我删除了很多类型检查,docblocks和类型提示来限制代码行/阅读时间;)
module.config.PHP
'form_elements' => [ 'factories' => [ CountryForm::class => CountryFormFactory::class,CountryFieldset::class => CountryFieldsetFactory::class,],
Country.PHP
class Country extends AbstractEntity // Creates $id + getter/setter { /** * @var string * @ORM\Column(name="name",type="string",length=255,nullable=false) */ protected $name; // Other properties // Getters/setters }
CountryController.PHP – 扩展AbstractActionController
public function editAction() // Here to show the params used to call function { return parent::editAction( Country::class,CountryForm::class,[ 'name' => 'country','options' => [] ],'id','admin/countries/view','admin/countries',['id'] ); }
AbstractActionController.PHP – (在这里出错了) – 由CountryController#editAction()使用
public function editAction ( $emEntity,$formName,$formOptions,$idProperty,$route,$errorRoute,array $routeParams = [] ) { //Check if form is set $id = $this->params()->fromRoute($idProperty,null); /** @var AbstractEntity $entity */ $entity = $this->getEntityManager()->getRepository($emEntity)->find($id); /** @var AbstractForm $form */ $form = $this->getFormElementManager()->get($formName,(is_null($formOptions) ? [] : $formOptions)); $form->bind($entity); /** @var Request $request */ $request = $this->getRequest(); if ($request->isPost()) { $form->setData($request->getPost()); if ($form->isValid()) { // HERE IS WHERE IT GOES WRONG -> ALL IS TRUE try { $this->getEntityManager()->flush(); } catch (\Exception $e) { //Print errors & return (removed,unnecessary) } return $this->redirectToRoute($route,$this->getRouteParams($entity,$routeParams)); } } return [ 'form' => $form,'validationMessages' => $form->getMessages() ?: '',]; }
CountryForm.PHP
class CountryForm extends AbstractForm { // This one added for SO,does nothing but call parent#__construct,which would happen anyway public function __construct($name = null,array $options) { parent::__construct($name,$options); } public function init() { //Call parent initializer. parent::init(); $this->add([ 'name' => 'country','type' => CountryFieldset::class,'options' => [ 'use_as_base_fieldset' => true,]); } }
CountryFormFactory.PHP
class CountryFormFactory extends AbstractFormFactory { public function createService(ServiceLocatorInterface $serviceLocator) { $serviceManager = $serviceLocator->getServiceLocator(); /** @var EntityManager $entityManager */ $entityManager = $serviceManager->get('Doctrine\ORM\EntityManager'); $form = new CountryForm($this->name,$this->options); $form->setObjectManager($entityManager); $form->setTranslator($serviceManager->get('translator')); return $form; } }
AbstractFormFactory.PHP – 使用MutableCreationOptionsInterface从Controller函数调用接收选项:$form = $this-> getFormElementManager() – > get($formName,(is_null($formOptions)?[]:$formOptions))
abstract class AbstractFormFactory implements FactoryInterface,MutableCreationOptionsInterface { protected $name; protected $options; /** * @param array $options */ public function setCreationOptions(array $options) { // Check presence of required "name" (string) parameter in $options $this->name = $options['name']; // Check presence of required "options" (array) parameter in $options $this->options = $options['options']; } }
CountryFieldset.PHP – 以上由CountryForm.PHP用作基本字段集
class CountryFieldset extends AbstractFieldset { public function init() { parent::init(); $this->add([ 'name' => 'name','required' => true,'type' => Text::class,'options' => [ 'label' => _('Name'),]); // Other properties } }
AbstractFieldset.PHP
abstract class AbstractFieldset extends Fieldset { use InputFilterAwareTrait; use TranslatorAwareTrait; protected $entityManager; public function __construct(EntityManager $entityManager,$name) { parent::__construct($name); $this->setEntityManager($entityManager); } public function init() { $this->add([ 'name' => 'id','type' => Hidden::class,]); } // Getters/setters for $entityManager }
CountryFieldsetFactory.PHP – 在这里,输入滤波器设置在FIELDSET上
class CountryFieldsetFactory extends AbstractFieldsetFactory { public function createService(ServiceLocatorInterface $serviceLocator) { parent::createService($serviceLocator); /** @var CountryRepository $entityRepository */ $entityRepository = $this->getEntityManager()->getRepository(Country::class); $fieldset = new CountryFieldset($this->getEntityManager(),$this->name); $fieldset->setHydrator(new DoctrineObject($this->getServiceManager()->get('doctrine.entitymanager.orm_default'),false)); $fieldset->setObject(new Country()); $fieldset->setTranslator($this->getTranslator()); // HERE THE INPUTFILTER IS SET ONTO THE FIELDSET THAT WAS JUST CREATED $fieldset->setInputFilter( $this->getServiceManager()->get('InputFilterManager')->get( CountryInputFilter::class,[ // These are the options read by the MutableCreationOptionsInterface 'object_manager' => $this->getEntityManager(),'object_repository' => $entityRepository,'translator' => $this->getTranslator(),] ) ); return $fieldset; } }
AbstractFieldsetFactory.PHP
abstract class AbstractFieldsetFactory implements FactoryInterface,MutableCreationOptionsInterface { protected $serviceManager; protected $entityManager; protected $translator; protected $name; public function setCreationOptions(array $options) { $this->name = $options['name']; } public function createService(ServiceLocatorInterface $serviceLocator) { /** @var ServiceLocator $serviceManager */ $this->serviceManager = $serviceLocator->getServiceLocator(); /** @var EntityManager $entityManager */ $this->entityManager = $this->getServiceManager()->get('Doctrine\ORM\EntityManager'); /** @var Translator $translator */ $this->translator = $this->getServiceManager()->get('translator'); } // Getters/setters for properties }
CountryFieldsetInputFilter.PHP
class CountryInputFilter extends AbstractInputFilter { public function init() { parent::init(); $this->add([ 'name' => 'name','filters' => [ ['name' => StringTrim::class],['name' => StripTags::class],'validators' => [ [ 'name' => StringLength::class,'options' => [ 'min' => 3,// This is just completely ignored 'max' => 255,]); // More adding } }
AbstractFieldsetInputFilter.PHP – 最后一个!