как избежать создания слага, который уже существует как маршрут "Symfony 4" - PullRequest
0 голосов
/ 05 марта 2020

У меня есть страница сущности, идентифицированная слизней. Также у меня есть действие для просмотра страницы в контроллере страницы:

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

Я ищу полезную практику для проверки слага (проверьте, есть ли в маршрутах) перед сохранением его в базе данных без использования префиксов. Пример :

маршрут существует: @route ("/blog")

проверьте, существует ли блог, прежде чем создавать слаг: /{slug} = /blog

спасибо

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Я создал проверку 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:)

0 голосов
/ 06 марта 2020

Вы можете использовать аннотацию UniqueEntity для проверки слаг на уникальность.

Например, в вашей сущности добавьте аннотацию 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);
}
...