Имитация псевдонимов URL-адреса Drupal в Laravel 5.2

В Drupal существует простая система перезаписи URL-адресов, в которой хранятся псевдонимы путей и реальный маршрут в базе данных.

Например:

/ category / hello => узел / 5

Я хотел бы подражать этой системе в Laravel.

Я знаю, как создать структуру базы данных. Я бы предпочел, чтобы предложения были переопределены и переназначили входящий запрос.

Я взглянул на маршрутизатор. Никаких событий на самом деле не торчат. Я бы хотел избежать добавления каждой перестановки в качестве статического маршрута. Я бы хотел, чтобы это было полностью динамичным.

Я читал промежуточное ПО с перенаправлением, но не знаю, лучший ли это путь. Имейте в виду, что псевдонимы могут быть чем угодно. Не существует набора шаблонов.

Фактический бизнес-пример для этого - приложение имеет иерархию категорий, например, для каталога на сайте электронной торговли. Для каждого пути динамическая страница должна существовать и, возможно, также разрешать передачу другим страницам.

Ex.

/ sports / football / nfl => App Http Controllers Category :: lp (2)

Даже что-то вроде:

/ sports / football / nfl /: game / lines => App Http Controllers Lines :: lp (: game)

Тем не менее, я не хочу иметь каждую перестановку в db. Просто базовый и разрешите все после того, как / sports / football / nfl / * пройдите в совершенно другое место.

Если я действительно помню в Symfony, это можно сделать с помощью специального маршрута. Однако я не вижу ничего подобного в Ларавеле. Если я просто что-то упустил. Похоже, вы либо добавляете статический маршрут, либо ничего не делаете, но я не занимался глубоким погружением в этот код, но может быть неправильно.

php,laravel,drupal,routing,

0

Ответов: 1


0

Я смог реализовать динамическую систему маршрутизации, создав свой собственный маршрут и добавив в коллекцию маршрутов вручную.

Пользовательский маршрут

use IlluminateRoutingRoute as BaseRoute;
use ModulesCatalogRoutingMatchingCategoryValidator;
use IlluminateRoutingMatchingMethodValidator;
use IlluminateRoutingMatchingSchemeValidator;
use IlluminateRoutingMatchingHostValidator;
use IlluminateHttpRequest;
use ModulesEventRepositoriesCategoryRepository;
use IlluminateRoutingControllerDispatcher;

/**
 * Special dynamic touting for catalog categories.
 */
class CategoryRoute extends BaseRoute {

    protected $validatorOverrides;

    /**
     * @param CategoryRepository
     */
    protected $categoryRepository;

    /**
     * Create a new Route instance.
     *
     * @param CategoryRepository $categoryRepository
     *   The category repository.
     */
    public function __construct(CategoryRepository $categoryRepository)
    {

        $this->categoryRepository = $categoryRepository;

        $action = [
            'uses'=> function() use ($categoryRepository) {
                $path = app('request')->path();
                $category = $categoryRepository->findOneByHierarchicalPath($path);
                $controller = app()->make('ModulesCatalogHttpControllersFrontendCategoryController');
                return $controller->callAction('getIndex', ['categoryId'=>$category->getId()]);
            }
        ];

        $action['uses']->bindTo($this);

        parent::__construct(['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'],'_catalog_category',$action);

    }

    /**
     * Determine if the route matches given request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  bool  $includingMethod
     * @return bool
     */
    public function matches(Request $request, $includingMethod = true)
    {
        $this->compileRoute();

        $validators = $this->getValidatorOverrides();

        foreach ($validators as $validator) {
            /*if (! $includingMethod && $validator instanceof MethodValidator) {
                continue;
            }*/

            if (! $validator->matches($this, $request)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Get the route validators for the instance.
     *
     * @return array
     */
    public function getValidatorOverrides()
    {
        if (isset($this->validatorOverrides)) {
            return $this->validatorOverrides;
        }

        $this->validatorOverrides = [
            new MethodValidator, new SchemeValidator,
            new HostValidator, /*new UriValidator,*/
            new CategoryValidator($this->categoryRepository)
        ];

        return $this->validatorOverrides;
    }

}

Пользовательский маркер проверки маршрута

<?php

namespace ModulesCatalogRoutingMatching;

use IlluminateRoutingMatchingValidatorInterface;
use IlluminateRoutingRoute;
use IlluminateHttpRequest;
use ModulesEventRepositoriesCategoryRepository;

class CategoryValidator implements ValidatorInterface
{

    protected $categoryRepository;

    public function __construct(CategoryRepository $categoryRepository) {
        $this->categoryRepository = $categoryRepository;
    }

    /**
     * Validate a given rule against a route and request.
     *
     * @param  IlluminateRoutingRoute  $route
     * @param  IlluminateHttpRequest  $request
     * @return bool
     */
    public function matches(Route $route, Request $request)
    {
        $path = $request->path() == '/' ? '/' : '/'.$request->path();
        $category = $this->categoryRepository->findOneByHierarchicalPath($path);
        return $category?true:false;
    }
}

Чтобы удовлетворить требованиям зависимости репозитория категории, мне также пришлось создать подписчика, который добавляет маршрут после загрузки всех поставщиков. Просто размещение в файле routes.php не будет работать, потому что не было гарантии, что все зависимости для IoC будут настроены, когда этот файл будет загружен.

Абонент Bootstrap

use ModulesCatalogRoutingCategoryRoute;
use ModulesEventRepositoriesCategoryRepository;
use IlluminateSupportFacadesRoute as RouteFacade;

class BootstrapSubscriber {

    public function subscribe($events) {

        $events->listen(
            'bootstrapped: IlluminateFoundationBootstrapBootProviders',
            'ModulesCatalogSubscribersBootstrapSubscriber@onBootstrappedBootProviders'
        );

    }

    public function onBootstrappedBootProviders($event) {

        $categoryRepository = app(CategoryRepository::class);
        RouteFacade::getRoutes()->add(new CategoryRoute($categoryRepository));

    }

}

Я, вероятно, расширюсь, но это основной способ сделать это.

PHP, Laravel, Друпал, маршрутизации,
Похожие вопросы