Aroused
@Aroused

Как получить имя роута в расширении Twig (тест)?

Пытаюсь реализовать тест:
{% if 'homepage' is is_page %}текущая страница "homepage"{% endif %}

Создал extension в src/Site/AppBundle/Twig/TwigExtension.php и зарегистрировал как сервис.
Но как получить имя роута, что бы выполнить проверку?
namespace Site\AppBundle\Twig;
class TwigExtension extends \Twig_Extension
{
    public function getTests()
    {
        return array(
            new \Twig_SimpleTest('is_page', array($this, 'isPageTest')),
        );
    }
    public function isPageTest($pageSlug = 'homepage')
    {
        return $pageSlug === 'homepage' ? true : false;
    }
    public function getName()
    {
        return 'twig_extension';
    }
}

services:
    site.twig_extension:
        class: Site\AppBundle\Twig\TwigExtension
        tags:
            - { name: twig.extension }
  • Вопрос задан
  • 655 просмотров
Решения вопроса 1
BoShurik
@BoShurik Куратор тега Symfony
Symfony developer
Если развивать идею из моего ответа на вопрос Как сделать активное меню? то:
namespace Site\AppBundle\Twig;

use Symfony\Component\HttpFoundation\Request;

class TwigExtension extends \Twig_Extension
{
    public function getTests()
    {
        return array(
            new \Twig_SimpleTest('match_route', array($this, 'matchRoute')),
        );
    }
    
    public function matchRoute(Request $request, $routeName, $routeParameters = array())
    {
        if (!$requestRouteName = $request->attributes->get('_route')) {
            return false;
        }

        if ($requestRouteName != $routeName) {
            return false;
        }

        if (empty($routeParameters)) {
            return true;
        }

        if (!$requestRouteParameters = $request->attributes->get('_route_params')) {
            return false;
        }

        $arrayIntersect = array_intersect_assoc($requestRouteParameters, $routeParameters);
        if (count($arrayIntersect) == count($routeParameters)) {
            return true;
        }

        return false;
    }

    public function getName()
    {
        return 'twig_extension';
    }
}


Использовать так:
{% if app.request is match_route('homepage') %}текущая страница "homepage"{% endif %}
{% if app.request is match_route('entry', { 'name': 'info' }) %}текущая страница "info"{% endif %}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
index0h
@index0h
PHP, Golang. https://github.com/index0h
Если я правильно понял и вы хотите проверить соответствие роута конкретному экшну, то решение есть по проще.

<?php

namespace MyVendor\MyApplication\AppBundle\Tests;

use KoKoKo\assert\Assert;
use KoKoKo\assert\exceptions\InvalidNotEmptyException;
use KoKoKo\assert\exceptions\InvalidNotObjectException;
use KoKoKo\assert\exceptions\InvalidStringException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

trait ControllerTrait
{
    /**
     * @param Request $request
     * @param string  $controllerClass
     * @param string  $actionName
     * @throws InvalidNotEmptyException
     * @throws InvalidNotObjectException
     * @throws InvalidStringException
     */
    public function checkRoute(Request $request, $controllerClass, $actionName)
    {
        Assert::assert($controllerClass, 'controllerClass')->string()->notEmpty();
        Assert::assert($actionName, 'actionName')->string()->notEmpty();

        /** @noinspection PhpUndefinedMethodInspection */
        static::$kernel->getContainer()->get('router_listener')->onKernelRequest(
            new GetResponseEvent($this->getKernel(), $request, HttpKernelInterface::MASTER_REQUEST)
        );

        $parameters = $request->attributes->all();

        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertInternalType('array', $parameters);
        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertArrayHasKey('_controller', $parameters);
        /** @noinspection PhpUndefinedMethodInspection */
        $this->assertSame($controllerClass . '::' . $actionName, $parameters['_controller']);
    }
}


Используется примерно так:
<?php

namespace MyVendor\MyApplication\AppBundle\Tests\Unit\Controller;

use MyVendor\MyApplication\AppBundle\Controller\MyController;
use MyVendor\MyApplication\AppBundle\Tests\ControllerTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\HttpFoundation\Request;

class MyControllerTest extends KernelTestCase
{
    use ControllerTrait;

    public function testMyRoute()
    {
        self::bootKernel();

        $request = new Request();

        $request->server->set('REQUEST_URI', '/MyRoute');
        $request->setMethod('POST');

        $this->checkRoute($request, MyController::class, 'myRouteOfMyController');
    }
}


Тут KoKoKo\assert\Assert - это либа для валидации входящих аргументов
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы