# Класс HttpSoft\Runner\MiddlewarePipeline

Класс, реализующий HttpSoft\Runner\MiddlewarePipelineInterface и отвечающий за построение конвейеров посредников PSR-15.

Исходный код на GitHub.

use HttpSoft\Runner\MiddlewarePipeline;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
 * @var Psr\Http\Message\ServerRequestInterface $request
 * @var Psr\Http\Server\RequestHandlerInterface $handler
 * @var Psr\Http\Server\MiddlewareInterface $siteMiddleware
 * @var Psr\Http\Server\MiddlewareInterface $userMiddleware
 */

$pipeline = new MiddlewarePipeline();

// Базовое использование

$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');

$response = $pipeline->handle($request);
// или
$response = $pipeline->process($request, $handler);

// Добавить пользовательского посредника

$handlerMiddleware = new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
};

$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$pipeline->pipe($handlerMiddleware);

$response = $pipeline->handle($request);

# Публичные методы

Оригинальное подробное описание методов смотрите в реализуемых интерфейсах:

# pipe

Добавляет в конвейер экземпляр Psr\Http\Server\MiddlewareInterface.

public function pipe(MiddlewareInterface $middleware, string $pathPrefix = null): void;

При указании префикса пути посредник прикрепляется к определенному пути и будет обрабатываться только в том случае, если путь URI запроса начинается с данного префикса.

// Доступно: `https://example.com` и `https://example.com/any`:
$pipeline->pipe($commonMiddleware);
// или
$pipeline->pipe($commonMiddleware, '');
// или
$pipeline->pipe($commonMiddleware, '/');

// Доступно: `https://example.com/api` and `https://example.com/api/any`:
$pipeline->pipe($apiMiddleware, '/api');

// Доступно: `https://example.com/api/admin` и `https://example.com/api/admin/any`:
$pipeline->pipe($apiAdminMiddleware, '/api/admin');
// но не доступно: `https://example.com/api` and `https://example.com/api/any`.

Префикс пути ДОЛЖЕН начинаться с корня, а начальный и конечный слэш необязательны (/path, path или path/).

// Один посредник может быть прикреплен к разным путям:
$pipeline->pipe($authMiddleware, 'blog');
$pipeline->pipe($authMiddleware, '/forum');

// К одному пути можно прикрепить несколько посредников:
$pipeline->pipe($authMiddleware, 'admin/');
$pipeline->pipe($adminMiddleware, '/admin/');

Этот метод определен в HttpSoft\Runner\MiddlewarePipelineInterface.

# process

По очереди запускает все посредники, которые были ранее добавлены в конвейер.

public function process(
    ServerRequestInterface $request, 
    RequestHandlerInterface $handler
): ResponseInterface;

Если в конвейер ранее не был добавлен посредник, который перехватывает обработчик и возвращает ответ, всегда будет возвращаться ответ сгенерированный $handler.

$pipeline = new MiddlewarePipeline();

// Вернет экземпляр `Psr\Http\Message\ResponseInterface` из `$handler`:
$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$response = $pipeline->process($request, $handler);

// Вернет экземпляр `Psr\Http\Message\ResponseInterface` из посредника:
$pipeline->pipe(new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
});
$response = $pipeline->process($request, $handler);

Этот метод определен в Psr\Http\Server\MiddlewareInterface.

# handle

По очереди запускает все посредники, которые были ранее добавлены в конвейер.

public function handle(ServerRequestInterface $request): ResponseInterface;

Внутри вызывает метод process(), в который передается обработчик выбрасывающий исключение HttpSoft\Runner\Exception\EmptyMiddlewarePipelineException. Если в конвейер ранее не был добавлен посредник, который перехватывает обработчик и возвращает ответ, всегда будет бросаться исключение.

$pipeline = new MiddlewarePipeline();

// Бросит `HttpSoft\Runner\Exception\EmptyMiddlewarePipelineException`:
$pipeline->pipe($siteMiddleware);
$pipeline->pipe($userMiddleware, '/user');
$response = $pipeline->handle($request);

// Вернет экземпляр `Psr\Http\Message\ResponseInterface`:
$pipeline->pipe(new class implements MiddlewareInterface {
    public function process(
        ServerRequestInterface $request, 
        RequestHandlerInterface $handler
    ): ResponseInterface {
        $response = new HttpSoft\Message\Response();
        $response->getBody()->write('Hello world!');
        return $response;
    }
});
$response = $pipeline->handle($request);

Этот метод определен в Psr\Http\Server\RequestHandlerInterface.