指定在symfony 2及更高版本中检索路由对象的方法

时间:2017-05-23 20:09:03

标签: php symfony

我找到了这个答案How to get the object with its translation using getRoute in Symfony?。但这是symfony 1.x的解决方案。

我使用注释进行路由,目前在symfony 3.1.9中虽然这有效,但我想指定用于从数据库加载id的对象的方法。原因是加入一些表,所以我的查询较少。

这可以在symfony 2/3中完成吗?

示例注释:

/**
 * View the recipe with the given ID if it is available in the current
 * locale.
 *
 * @param Request $request
 * @param \MyName\MyBundle\Entity\Recipe $object
 * @return Response A Response instance
 * @throws NotFoundHttpException
 *
 * @Route("/{id}", options={"method" = "ernst"})
 * @Method({"GET"})
 * @Breadcrumb("{object.name}")
 */
public function viewAction(Request $request, \MyName\MyBundle\Entity\Recipe $object = null)
{
    // do stuff
}

食谱有它自己的存储库:

/**
 * Recipe
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="MyName\MyBundle\Repository\RecipeRepository")
 */
class Recipe
{
}

1 个答案:

答案 0 :(得分:0)

gps_sflover给出的方向很好。控制器现在看起来像:

/**
 * View the recipe with the given ID if it is available in the current
 * locale.
 *
 * @param Request $request
 * @param \MyName\MyBundle\Entity\Recipe $object
 * @return Response A Response instance
 * @throws NotFoundHttpException
 *
 * @Route("/{id}")
 * @ParamConverter("object", options={
 *     "repository_method" = "findForLocale",
 *     "mapping": {"_locale": "locale", "id": "id"},
 *     "map_method_signature" = true
 * })
 * @Method({"GET"})
 * @Breadcrumb("{object.name}")
 */
public function viewAction(Request $request, \MyName\MyBundle\Entity\Recipe $object)
{
    // do stuff
}

Recipe存储库现在有这个方法:

class RecipeRepository extends EntityRepository
{
    /**
     * Return the recipe for the given id associated with the needed information
     * to show on the recipe detail page. The current locale is set as a condition.
     *
     * @param string $locale
     * @param int $id
     * @return \Vaarties\DwehBundle\Entity\Recipe
     */
    public function findForLocale($locale, $id)
    {
        $queryBuilder = $this->findAllForLocale($locale);

        $queryBuilder
            ->andWhere('e.id = :id')
            ->setParameter('id', $id);

        return $queryBuilder
            ->getQuery()
            ->getOneOrNullResult();
    }

    /**
     * Find all objects of the current entity joined with all off its translations
     * for the language in the given locale.
     *
     * TODO: See if the complete locale needs to be checked and the language
     *       only as a fallback. See https://github.com/KnpLabs/DoctrineBehaviors/issues/309
     *
     * @param string $locale
     * @return QueryBuilder
     */
    public function findAllForLocale($locale)
    {
        $language = $this->getLanguageFromLocale($locale);

        $queryBuilder = $this->findAllJoinedToTranslation();

        $queryBuilder
            ->where('t.locale = :locale')
            ->setParameter('locale', $language);

        return $queryBuilder;
    }

    /**
     * Find all objects of the current entity joined with all off its translations.
     *
     * @return QueryBuilder
     */
    public function findAllJoinedToTranslation()
    {
        // A QueryBuilder is returned for use in the KnpPaginatorBundle for it being
        // able to add sorting and filtering.
        return $this->createQueryBuilder('e')
                ->select('e, t')
                ->join('e.translations', 't');
    }

    /**
     * The language part from the locale is returned. If the locale doesn't contain
     * an underscore, the whole locale is returned.
     *
     * @param string $locale
     * @return string
     */
    protected function getLanguageFromLocale($locale)
    {
        $localeParts = explode('_', $locale);
        if (is_array($localeParts)) {
            $language = reset($localeParts);
        } else {
            $language = $locale;
        }

        return $language;
    }
}