php - Symfony3 – Form submission with clearMissing – nullified properties always – how to fix this? -


i'm using "symfony ~3.3".

if send in request bar property (without zyx because don't need change it), error:

type error: argument 1 passed appbundle\entity\foo::setzyx() must of type string, null given, called in /full/path/to/project/vendor/symfony/symfony/src/symfony/component/propertyaccess/propertyaccessor.php on line 636

my question simple: why clearmissing parameter ignored , how achive editing selected properties?


some code here:

controller:

class foocontroller extends controller {     /**      * @rest\patch("/foo/{id}", requirements={"id": "\d+"})      *      * @rest\requestparam(name="bar", nullable=true)      * @rest\requestparam(name="zyx", nullable=true)      *      * @param int          $id      * @param paramfetcher $pf      *      * @return response      *      * @throws \symfony\component\httpkernel\exception\notfoundhttpexception      * @throws \symfony\component\httpkernel\exception\badrequesthttpexception      */     public function editaction(int $id, paramfetcher $pf) : response     {         $foo = $this->repository->find($id);         if (!$foo) throw $this->createnotfoundexception();          $form = $this->createform(footype::class, $foo);         $form->submit($pf->all(), false); // <––––– here          if (!$form->issubmitted() || !$form->isvalid())             throw new badrequesthttpexception($this->view($form->geterrors(true))->getdata());          $foo = $form->getdata();         $this->em->merge($foo);         $this->em->flush();          return $this->responder->respond($foo);     } } 

doctrine entity:

/**  * @orm\entity()  */ class foo {     /**      * @assert\notblank()      * @assert\length(min="3", max="190")      * @orm\column(type="string", length=190)      */     private $bar;      /**      * @assert\notblank()      * @assert\length(min="3")      * @orm\column(type="text")      */     private $zyx;      public function __construct(string $bar, string $zyx)     {         $this->bar = $bar;         $this->zyx = $zyx;     }      public function getbar() : string { return $this->bar; }     public function getzyx() : string { return $this->zyx; }      public function setbar(string $v) { $this->bar = $v; }     public function setzyx(string $v) { $this->zyx = $v; } } 

form type:

class footype extends abstracttype {     public function buildform(formbuilderinterface $builder, array $options)     {         $builder             ->add('bar', texttype::class)             ->add('zyx', texttype::class)         ;     }      public function configureoptions(optionsresolver $resolver)     {         $resolver->setdefaults([             'data_class'      => foo::class,             'csrf_protection' => false,             // todo better way workaround constructor requirements?             'empty_data'      => new foo('_', '_'),         ]);     } } 

changing controller solve issue.. but.. that's ugly , decreases maintainability. here other way?

class foocontroller extends controller {     public function editaction(int $id, paramfetcher $pf) : response     {         $foo = ...;          $form = $this->createform(footype::class, $foo);          $submit = [];         $bar = $pf->get('bar');         $zyx = $pf->get('zyx');         if (!empty($bar)) $submit['bar'] = $bar;         if (!empty($zyx)) $submit['zyx'] = $zyx;         $form->submit($submit, false);          ...     } } 

um doesn't work?

      public function __construct(string $bar, string $zyx = ""){           if( strlen( $zyx  ) > 0 )  $this->zyx = $zyx;           $this->zyx = $zyx;          ...       } 

if felt inclined cheat on setter this

  public function __set( $key, $value ){       if( !method_exits( $this, '_'.$key ) ) throw new exception('unknown method' );        if( !empty( $value ) )  $this->'_'.$key( $value );    }    protected function  _setzyx(string $v) { $this->zyx = $v; } 

then when call setzyx() ( undefined ) uses magic set method filters out empty values.... don't use symphony don't know if check method_exists() etc.. thought fun

update

looking @ update can way too

    $submit = [];     $submit['bar'] = $pf->get('bar');     $submit['zyx'] = $pf->get('zyx');      $submit = array_filter( $submit ); //you may need custom callback,      $form->submit($submit, false); 

but may more maintainable way, extend $form class , override submit function , bake in way.

i not symphony user ( don't know convention overriding stuff ) after extending $form class

  public function submit( $submit, $arg1, $filter = false ){       //sorry not sure second arg is, anyway        if( $filter ){           if( gettype( $filter ) == 'boolean' )               $submit = array_filter( $submit );           else               $submit = array_filter( $submit, $filter );       }        parent::submit( $submit, $arg1 );   } 

then it's backed class, , can either call true or give closure use filter, such

    $form2->submit( $submit, false, function( $item ){          return strlen( $item );     }); 

you wrap in function inside base controller or helper class ( , pass $form ), don't need code on place.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

.htaccess - ERR_TOO_MANY_REDIRECTS htaccess -