symfony - Symfony2 and ParamConverter(s) -


accessing route /message/new i'm going show form sending new message 1 or more customers. form model has (among others) collection of customer entities:

class myformmodel {    /**     * @var arraycollection     */     public $customers; } 

i'd implement automatic customers selection using customers parameters, this:

message/new?customers=2,55,543 

this working splitting on , , query getting customers:

public function newaction(request $request) {     $formmodel = new myformmodel();      // "customers" parameter     $customersids = explode($request->get('customers'), ',');      // if found in "customers" parameter entities     if(!empty($customersids)) :          $repo  = $this->getdoctrine()->getrepository('acmehellobundle:customer');         $found = $repo->findallbyidsarray($customersids);          // assign found customer entities         $formmodel->customers = $found;     endif;      // go on showing form } 

how can same using symfony 2 converters? like:

public function newaction(request $request, $selectedcustomers) { } 

answer self: there not such thing make life easy. i've coded quick , dirty (and possibly buggy) solution i'd share, waiting best one.

edit warning: not going work 2 parameter converters same class.

url example

/mesages/new?customers=2543,3321,445 

annotations:

/**  * @route("/new")  * @method("get|post")  * @paramconverter("customers",  *     class="doctrine\common\collections\arraycollection", options={  *         "finder"    = "getfindallwithmobilebyuserquerybuilder",  *         "entity"    = "acme\hellobundle\entity\customer",  *         "field"     = "id",  *         "delimiter" = ",",  *     }  * )  */ public function newaction(request $request, arraycollection $customers = null) { } 

option delimiter used split get parameter while id used adding where id in... clause. there both optional.

option class used "signature" tell converter should support it. entity has fqcn of doctrine entity while finder repository method invoked , should return query builder (default 1 provided).

converter

class arraycollectionconverter implements paramconverterinterface {     /**      * @var \symfony\component\dependencyinjection\containerinterface      */     protected $container;      public function __construct(containerinterface $container)     {         $this->container = $container;     }      function apply(request $request, configurationinterface $configuration)     {         $name    = $configuration->getname();         $options = $this->getoptions($configuration);          // se request attribute empty collection (as default)         $request->attributes->set($name, new arraycollection());          // if request parameter missing or empty return         if(is_null($val = $request->get($name)) || strlen(trim($val)) === 0)             return;          // if splitted values empty array return         if(!($items = preg_split('/\s*'.$options['delimiter'].'\s*/', $val,             0, preg_split_no_empty))) return;          // repository , logged user         $repo = $this->getentitymanager()->getrepository($options['entity']);         $user = $this->getsecuritycontext->gettoken()->getuser();          if(!$finder = $options['finder']) :             // create new default query builder user_id clause             $builder = $repo->createquerybuilder('e');             $builder->andwhere($builder->expr()->eq("e.user", $user->getid()));              else :                 // call finder method on repository                 $builder = $repo->$finder($user);         endif;          // edit builder , add in $items clause         $alias   = $builder->getrootalias() . "." . $options['field'];         $wherein = $builder->expr()->in($alias, $items);         $result  = $builder->andwhere($wherein)->getquery()->getresult();          // set request attribute , we're done         $request->attributes->set($name, new arraycollection($result));     }      public function supports(configurationinterface $configuration)     {         $class = $configuration->getclass();          // check if class arraycollection doctrine         if('doctrine\common\collections\arraycollection' !== $class)             return false;          $options = $this->getoptions($configuration);         $manager = $this->getentitymanager();          // check if $options['entity'] dcontrine 1         try         {             $manager->getclassmetadata($options['entity']);             return true;         }         catch(\doctrine\orm\mapping\mappingexception $e)         {             return false;         }     }      protected function getoptions(configurationinterface $configuration)     {         return array_replace(             array(                 'entity'         => null,                 'finder'         => null,                 'field'          => 'id',                 'delimiter'      => ','              ),             $configuration->getoptions()         );     }      /**      * @return \doctrine\orm\entitymanager      */     protected function getentitymanager()     {         return $this->container->get('doctrine.orm.default_entity_manager');     }      /**      * @return \symfony\component\security\core\securitycontext      */     protected function getsecuritycontext()     {         return $this->container->get('security.context');     } } 

service definition

arraycollection_converter:   class: acme\hellobundle\request\arraycollectionconverter   arguments: ['@service_container']   tags:     - { name: request.param_converter} 

Comments

Popular posts from this blog

jquery - Invalid Assignment Left-Hand Side -

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -