如何使用注释路由继承父方法?

时间:2017-07-14 16:29:14

标签: php symfony routing

使用Symfony 3.4。想要将所有功能保留在父抽象类中,只需在子项中设置路由前缀:

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';
    }
}

但我得到“没有为”GET / daily_tasks /“找到路线。有什么问题?如何实现我的想法?不希望在每个子控制器中复制带注释的每个操作。

1 个答案:

答案 0 :(得分:2)

好的,因为我只有这个例子,这看起来就像你想要实现的那样:

class TaskAbstractController extends Controller
{
    /**
     * Lists all Task entities.
     *
     * @Route("/{prefix}", name="tasks_index", requirements={"prefix":"daily_task|add_some_more"})
     * @Method("GET")
     */
    public function indexAction($prefix)
    {
        $em = $this->getDoctrine()->getManager();

        /** @var TaskFactory $taskFactory */
        $taskFactory = $this->container->get('task_factory');
        $task        = $taskFactory->get($prefix);

        $tasks = $em->getRepository($task->getTargetClassName())->findAll();

        return $this->render('@App/'.$prefix.'/index.html.twig',
            [
                'tasks'        => $tasks,
                'delete_forms' => $this->generateDeleteFormsViews($tasks),
            ]);
    }
}

class TaskFactory
{
    public function get(string $prefix): TaskInterface
    {
        $map = [
            'daily_task' => DailyTask::class,
        ];

        if (isset($map[$prefix])) {
            return new $map[$prefix];
        }

        throw new \RuntimeException('task not found');
    }
}

interface TaskInterface
{
    public function getTargetClassName(): string;
}

动态制作路线并将所有可能的值定义为要求。无论如何,你必须在@Route()方法中做类似的事情。

然后,TaskFactory根据$prefix确定孩子的内容。