如何避免创建已作为路由“Symfony 4”存在的 slug

问题描述 投票:0回答:2

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

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

谢谢

php validation routes symfony4 slug
2个回答
0
投票

您可以使用

UniqueEntity
注释来检查 slug 的唯一性。

例如,在您的实体中添加

UniqueEntity
注释和
slug
字段。

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

0
投票

我创建了一个验证 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 :)

© www.soinside.com 2019 - 2024. All rights reserved.