Answer the question
In order to leave comments, you need to log in
How to inherit parent controller methods when routing via annotations?
Symfony 3.4.
I want to store all the functionality in an abstract controller, and only prefixes for routing in child controllers:
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
abstract class TaskAbstractController extends Controller
{
/**
* Lists all Task entities.
*
* @Route("/", name="tasks_index")
* @Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$tasks = $em->getRepository($this->getTargetClassName())->findAll();
return $this->render('@App/' . $this->getPrefix() . '/index.html.twig', array(
'tasks' => $tasks,
'delete_forms' => $this->generateDeleteFormsViews($tasks)
));
}
/**
* Daily task controller.
*
* @Route("daily_tasks")
*/
class DailyTaskController extends TaskAbstractController
{
protected function getPrefix(): string
{
return 'daily_task';
}
protected function getTargetClassName(): string
{
return 'AppBundle:DailyTask';
}
}
Answer the question
In order to leave comments, you need to log in
I found a solution for what I wanted: routing annotations are not read from abstract classes, so I extended the abstract controller with some intermediate one, and added routing actions to it:
/**
*
* @Route("/{id}", name="task_show")
* @Method("GET")
*
*/
public function showAction(string $prefix, string $id)
{
return parent::{__FUNCTION__}(...func_get_args());
}
/**
* Lists all Task entities.
*
* @Route("/{prefix}", requirements={"prefix":"daily_tasks|events"})
*/
class TaskController extends Controller
class TaskFactory
{
private $map = [
'daily_tasks' => DailyTask::class,
'events' => Event::class,
'todo' => Todo::class,
'periodical' => Periodical::class,
'until' => Until::class,
'ponder' => Ponder::class
];
public function get(string $prefix): TaskInterface
{
$class = $this->getTargetClassName($prefix);
return new $class;
}
public function getTargetClassName(string $prefix): string
{
if (isset($this->map[$prefix])) {
return $this->map[$prefix];
}
throw new \RuntimeException('Task not found');
}
}
You can't do this with YAML and XML. If you really want to, create a routing.php file and upload it:
# app/config/routing.yml
routes:
resource: 'routing.php'
Beautiful answers... About impossibility
But it is possible to make.
Upd: option two for the question author's "obvious idea"
https://github.com/sfortop/symfony-routing-inheritance
app:
resource: "@AppBundle/Controller/DefaultController.php"
type: annotation
demo:
resource: "@AppBundle/Controller/DemoController.php"
prefix: "/demo"
type: annotation
other:
resource: "@AppBundle/Controller/OtherController.php"
prefix: "/other"
type: annotation
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
abstract class AbstractController extends Controller
{
/**
* @param Request $request
* @return Response
* @Route("/")
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,
]);
}
/**
* @param Request $request
* @Route("/demo/")
* @return Response
*/
public function demoAction(Request $request)
{
return new Response(sprintf("I'm %s controller", static::class));
}
}
namespace AppBundle\Controller;
class DefaultController extends AbstractController {}
OtherController.php
namespace AppBundle\Controller;
class OtherController extends AbstractController {}
namespace AppBundle\Controller;
class DemoController extends AbstractController {}
Set up routing not in annotations, but in yaml. Yes, it won’t be possible to inherit there either, but you don’t need to configure routing in controllers.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question