INTERNAL. Нужен для максимального разнесения функционала по пакетам. Плюс борьба с копипастой инструментов на проектах.
-
composer require proklung/bitrixsymfonyrouterbundle
-
Подключение бандла в
standalone_bundles.php
Файл symfony_router.yaml
в конфигурации бандлов:
enabled
- Использовать бандл. По умолчаниюtrue
.controller_annotations_path
- массив с путями к контроллерам, использующим аннотации.router_cache_path
- путь к кэшу аннотаций (вида%kernel.cache.dir%/routes
). По умолчаниюnull
. Если задан, то роуты будут кэшироваться.router_config_file
- путь к файлу с конфигурацией роутов. По умолчаниюlocal/configs/routes.yaml
. Файл может быть в любом поддерживаемом Symfony формате - Yaml, PHP, XML и т.д.router_check_exists_controller
- проверять на существование классы-контроллеры. По умолчаниюfalse
.
С версии 21.400.0
(от 16.07.2021) главного модуля в Битриксе появился сносный роутер.
Чтобы использовать привычный способ конфигурирования роутов через Yaml.
Файл описания маршрутов (например, /local/routes/web.php
):
use Prokl\ServiceProvider\ServiceProvider;
use Bitrix\Main\Routing\Controllers\PublicPageController;
use Prokl\BitrixSymfonyRouterBundle\Services\Agnostic\BaseRoutesConfigurator;
use Prokl\BitrixSymfonyRouterBundle\Services\Utils\BitrixRouteConvertor;
use Bitrix\Main\Routing\RoutingConfigurator;
// Не обязательно. Смотри ниже.
$container = ServiceProvider::instance();
$agnosticRouter = new BaseRoutesConfigurator(
$_SERVER['DOCUMENT_ROOT'] . '/local/configs/bitrix_routes.yaml', // Конфиг роутов
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/cache/routes', // Кэш; если null - без кэширования.
$_ENV['DEBUG']
);
$routeCollection = $agnosticRouter->getRoutes();
$routeConvertor = new BitrixRouteConvertor($routeCollection);
// Не обязательно. Без контейнера контроллеры будут инстанцироваться через new,
// а не через контейнер. Но тогда уже без разрешения зависимостей.
$routeConvertor->setContainer($container);
return function (RoutingConfigurator $routes) use ($container, $routeConvertor, $routeCollection) {
$routeConvertor->convertRoutes($routes);
};
В случае, если контейнер подключается, то возможна краткая форма:
use Prokl\ServiceProvider\ServiceProvider;
use Bitrix\Main\Routing\Controllers\PublicPageController;
use Prokl\BitrixSymfonyRouterBundle\Services\Utils\BitrixRouteConvertor;
use Bitrix\Main\Routing\RoutingConfigurator;
// Не обязательно. Смотри ниже.
$container = ServiceProvider::instance();
$routeCollection = $container->get('bitrix_native_routes.routes.collection');
$routeConvertor = new BitrixRouteConvertor($routeCollection);
// Не обязательно. Без контейнера контроллеры будут инстанцироваться через new,
// а не через контейнер. Но тогда уже без разрешения зависимостей.
$routeConvertor->setContainer($container);
return function (RoutingConfigurator $routes) use ($container, $routeConvertor, $routeCollection) {
$routeConvertor->convertRoutes($routes);
$routes->get('/', new PublicPageController('/index.php'));
};
Пример файла с конфигурацией роутов (обычный yaml файл с роутами для Symfony):
first_bitrix_route:
path: /foo/{param}/
controller: 'Prokl\BitrixSymfonyRouterBundle\Tests\Fixture::cacheAction'
methods: GET|POST
requirements:
param: '\d+'
defaults:
param: 'Russia'
# Старые статические страницы
# / => /index.php
public_page:
path: /
controller: ''
defaults:
_public: true # Ключевой признак
Если установлен Битрикс с версией модуля младше 21.400.0
, то соответствующие сервисы будут
удалены из бандла на стадии компиляции.
init.php
:
use Prokl\BitrixSymfonyRouterBundle\Services\Agnostic\BaseRoutesConfigurator;
use Prokl\BitrixSymfonyRouterBundle\Services\Agnostic\Router;
use Prokl\BitrixSymfonyRouterBundle\Services\Agnostic\BitrixInitializerRouter;
$agnosticRouter = new BaseRoutesConfigurator(
$_SERVER['DOCUMENT_ROOT'] . '/local/configs/standalone_routes.yaml',
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/cache/routes_agnostic', // Кэш; если null - без кэширования.
$_ENV['DEBUG'] // Режим отладки или нет
);
$agnosticRouterInstance = new Router(
$agnosticRouter->getRouter(),
new BitrixInitializerRouter()
);
Все. Подтянутся роуты из /local/configs/standalone_routes.yaml
. Автоматически подцепятся события.
Допускается наличие нескольких таких "агностических" роутеров в один момент.
- Экземпляр
Symfony\Component\Routing\Router
(роуты Symfony) можно получить снаружи так:
$router = \Prokl\BitrixSymfonyRouterBundle\Services\Agnostic\SymfonyRoutes::getInstance();
- Как загрузить роуты бандлы:
В файле Extension
бандла:
public function load(array $configs, ContainerBuilder $container) : void
{
// ....
$this->loadRoutes(__DIR__ . '/../Resources/config', 'routes.yaml');
}
/**
* Загрузить роуты в бандле.
*
* @param string $path Путь к конфигу.
* @param string $config Конфигурационный файл.
*
* @return void
*
* @throws InvalidArgumentException Нет класса-конфигуратора роутов.
*/
private function loadRoutes(string $path, string $config = 'routes.yaml') : void
{
$routeLoader = new \Symfony\Component\Routing\Loader\YamlFileLoader(
new FileLocator($path)
);
$routes = $routeLoader->load($config);
if (class_exists(InitRouter::class)) {
InitRouter::addRoutesBundle($routes);
return;
}
throw new InvalidArgumentException('Class InitRouter not exist.');
}
Или воспользоваться трэйтом Prokl\BitrixSymfonyRouterBundle\Services\Utils\LoaderBundleRoutesTrait
,
куда вынесен этот метод.