Here's the code I'm testing at present (I know, i know, TDD!) Some of the 
interface names are obviously wrong but are the same as I proposed earlier.

<?php


namespace Manneken\Http\Middleware;


use Ds\Stack as DsStack;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Interop\Http\Factory\ResponseFactoryInterface as InteropFactory;
use Manneken\Http\ExchangeInterface;
use Manneken\Http\ResponseFactoryInterface;


class Stack implements ExchangeInterface, ResponseFactoryInterface
{
    private $stack;
    private $factory;


    public function __construct(DsStack $stack, InteropFactory $factory)
    {
        $this->stack = $stack;
        $this->factory = $factory;
    }


    public function addMiddleware(MiddlewareInterface $middleware)
    {
        $this->stack->push($middleware);
    }


    public function exchange(RequestInterface $request): ResponseInterface
    {
        $message = $this->iterateOverInboundStackWithMessage(
            $this->getInboundStackFromStack(),
            $request
        );


        if (is_a($message, ResponseInterface::class)) {
            return $message;
        }


        return $this->iterateOverOutboundStackWithMessage(
            $this->getOutboundStackFromStack(),
            $this->createResponseInstance()
        );
    }


    public function createResponseInstance(): ResponseInterface
    {
        return $this->factory->createResponse();
    }


    private function getInboundStackFromStack(): array
    {
        return array_filter($this->stack->toArray(), function ($middleware) 
{
            return is_a($middleware, RequestMiddlewareInterface::class);
        });
    }


    private function iterateOverInboundStackWithMessage(array $stack, 
MessageInterface $message): MessageInterface
    {
        foreach ($stack as $middleware) {
            $message = $middleware->processRequest($message);


            if (is_a($message, ResponseInterface::class)) {
                return $message;
            }
        }


        return $message;
    }


    private function getOutboundStackFromStack(): array
    {
        return array_reverse(array_filter($this->stack->toArray(), function 
($middleware) {
            return is_a($middleware, ResponseMiddlewareInterface::class);
        }));
    }


    private function iterateOverOutboundStackWithMessage(array $stack, 
MessageInterface $message): MessageInterface
    {
        foreach ($stack as $middleware) {
            $message = $middleware->processRequest($message);
        }


        return $message;
    }
}

So, the addMiddleware function doesn't care if it's a request, response, or 
both middleware types, and the stack is split properly at runtime.

I hope this example explains it better.


-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to php-fig+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/518e497a-d832-4e4e-86f3-5a3d6bda042a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to