medunes
medunes

Reputation: 586

Include the same action in all controllers with a dynamic route in Symfony?

I am building a service (called "dynamic_query") which I use to expose all entities to a REST API, so that if I have an entity diagram like this one:

[continent--(has many)-->country--(has many)-->city]

I can get countries (JSON list) that are in let say Africa through the URL:

http://www.example.com/country/api/?continent=africa

And even for indirectly related entities, I still can get results: for example, to list all cities which belong to countries situated in Europe:

http://www.example.com/city/api/?continent=europe

The service is ready and tested, and here is how I use it within the City Controller taken as an example:

/**
* City controller.
*
* @Route("city")
*/
class CityController extends Controller
{
    /**
     *
     * @Route("/api/", name="city_api",options = { "expose" = true })
     * @Method("GET")
     * 
     */
     public function apiAction(Request $request)
     {

        $conditions=$request->query->all();

        $results=$this->get("app.dynamic_query")
                      ->narrow("city",$conditions);

        return new Response($results);
      }
}

What I'm looking for right now is to find a way to "duplicate" this apiAction() ** with its route** and make it available in every entity in my bundle, so that whenever I access:

http://www.example.com/entity/api/?arg_1=val_1&arg_2=val_2&arg_n=val_n

I got exactly the same logic shown above in the apiAction(), except the $entity_name and the route name/uri should change dynamically to fit the api query

Upvotes: 1

Views: 555

Answers (1)

JeromeH
JeromeH

Reputation: 61

In addition to mickadoo comment's, in my case this is what i use to do it:

routing.yml:

list_entities:
    path:     /admin/list/{class}/{page}
    defaults: { _controller: AdminBundle:Admin:listEntities, page : 1 }
    requirements:
        methods:  GET
        class: region|department|city|user|type|category|offer|report|comment
        page: \d+

AdminController:

class AdminController extends Controller{

    private $entities_bundle = array('region' => 'LocalizationBundle',
                                    'department' => 'LocalizationBundle',
                                    'city' => 'LocalizationBundle',
                                    'user' => 'MainBundle',
                                    'type' => 'MainBundle',
                                    'category' => 'MainBundle',
                                    'offer' => 'MainBundle',
                                    'report' => 'MainBundle',
                                    'comment' => 'MainBundle');

    private $entity_entities = array('region' => 'regions',
                                    'department' => 'departments',
                                    'city' => 'cities',
                                    'user' => 'users',
                                    'type' => 'types',
                                    'category' => 'categories',
                                    'offer' => 'offers',
                                    'report' => 'reports',
                                    'comment' => 'comments');

...

public function listEntitiesAction($class, $page = 1){

    $em = $this->getDoctrine()->getManager();
    $entities = $em->getRepository($this->entities_bundle[$class].":".ucfirst($class))->findPaginateListForAdmin(30, $page);

    //Your logic

    return $this->render('AdminBundle:Admin:list_'.$this->entity_entities[$class].'.html.twig', array('parameters' => $parameters));


}

It's not for REST API but i think you can adapt this code easily for your case. But you need mutual controller.

Upvotes: 1

Related Questions