Нашел решение для того, что хотел: аннотации роутинга не читаются из абстрактных классов, поэтому я расширил абстрактный контроллер неким промежуточным, и прописал в нём экшены с роутингом:
/**
*
* @Route("/{id}", name="task_show")
* @Method("GET")
*
*/
public function showAction(string $prefix, string $id)
{
return parent::{__FUNCTION__}(...func_get_args());
}
После чего я уже наследовал этот контроллер другими... Но от этой идеи я отказался, так как имена роутов выходили одинаковыми и сделать их динамическими (с помощью префикса, как URL) не представляется возможным. Потому я просто сделал один контроллер:
/**
* Lists all Task entities.
*
* @Route("/{prefix}", requirements={"prefix":"daily_tasks|events"})
*/
class TaskController extends Controller
универсальный для всех классов - с каким классом сущностей и папками работать он определяет на основе параметра prefix. Так что сделал фабрику:
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');
}
}
Только вот теперь инъекция сущностей в декларацию экшенов перестала работать, приходится их самостоятельно создавать / доктриной загружать.