【问题标题】:how to avoid creating a slug that already exists as a Route "Symfony 4"如何避免创建已作为路线“Symfony 4”存在的 slug
【发布时间】:2020-06-18 08:53:38
【问题描述】:

我有 slug 标识的实体 Page。我还可以在页面控制器中查看页面:

class PageController extends AbstractController
{
   /**
    * @Route("/{slug}", name="fronend_page")
    */
   public function show(Page $page)
   {
       return $this->render("font_end/page/show.html.twig", [
           "page" => $page,
       ]);
   }
}

我正在寻找一种好的做法来验证 slug(检查路由中是否存在),然后再将其保存在数据库中而不使用前缀 示例:

路由存在:@route ("/blog")

在创建 slug 之前检查博客是否存在:/{slug} = /blog

谢谢

【问题讨论】:

    标签: validation routes symfony4 slug


    【解决方案1】:

    您可以使用 UniqueEntity 注释来检查 slug 的唯一性。

    例如,在您的实体中添加带有slug 字段的UniqueEntity 注释。

    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @ORM\Entity
     * @UniqueEntity("slug")
     */
    class Page
    {
        /**
         * @ORM\Column(type="string", length=255, unique=true)
         * @Assert\NotBlank
         */
        private $slug;
    
        public function __construct(string $slug)
        {
            $this->slug = $slug;
        }
    }
    

    然后您可以在控制器中创建一些服务或进行验证。

       /**
        * @Route("/{slug}")
        */
       public function show($slug, ValidatorInterface $validator)
       {
           $page = new Page($slug);
           $errors = $validator->validate($author);
    
           if (count($errors) > 0) {
               // handle errors
           }
    
           // save entity 
       }
    

    更新:

    为了检查已经存在的路线,你可能可以这样做

    public function isRouteExist(string $slug): bool
    {
        /** @var Symfony\Component\Routing\RouterInterface $router */
        $routes = array_filter(array_map(function (\Symfony\Component\Routing\Route $route) {
            if (!$route->compile()->getVariables()) {
                return $route->getPath();
            }
    
            return null;
        }, $router->getRouteCollection()->all()));
    
        return in_array(sprintf('/%s', $slug), $routes, true);
    }
    

    【讨论】:

    • 感谢 Ihor,但我想检查 slug 是否存在 Routes 而不是 slug
    • 假设我们有路由 : Route("/blog") 并且我们有一个带有路由的页面系统 : Route("/{slug}") 在创建页面时,它们有可能具有相同的名称“博客”。我正在寻找一种方法来检查现有路线的 slug
    • 更新答案。
    【解决方案2】:

    我创建了一个验证 Symfony:

    class ContainsCheckSlugValidator extends ConstraintValidator
    {
    
       private $router;
    
       public function __construct(UrlGeneratorInterface $router)
       {
           $this->router = $router;
       }
    
       public function validate($value, Constraint $constraint)
       {
           if (!$constraint instanceof ContainsCheckSlug) {
               throw new UnexpectedTypeException($constraint, ContainsCheckSlug::class);
           }
    
           // custom constraints should ignore null and empty values to allow
           // other constraints (NotBlank, NotNull, etc.) take care of that
           if (null === $value || "" === $value) {
               return;
           }
           $routes = $this->router->getRouteCollection()->all();
           $routes = array_map(function($route){
               return $route->getPath();
           },$routes);
           if (in_array(sprintf("/{_locale}/%s/", $value), $routes, true)) {
               $this->context->buildViolation($constraint->message)
                   ->setParameter("{{ string }}", $value)
                   ->addViolation();
           }
       }
    }
    

    谢谢@Ihor_Kostrov :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 2020-10-11
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 2022-09-24
      • 2023-04-09
      相关资源
      最近更新 更多