Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Provide support for zend-stratigility 2.2.2 #293

Closed

Conversation

thexpand
Copy link
Contributor

Travis was failing on latest builds on all platforms. I've ran composer update and came across a deprecation error when I ran the unit tests. Callable double-pass middleware must be decorated in order to work with the new version of zend-stratigility.
That's what this hotfix is all about - it includes the updated Composer files and the decorated middleware.

src/MiddlewareListener.php Outdated Show resolved Hide resolved
src/MiddlewareListener.php Outdated Show resolved Hide resolved
@@ -146,6 +147,19 @@ private function createPipeFromSpec(
throw InvalidMiddlewareException::fromMiddlewareName($middlewareName);
}

// Decorate double-pass middleware
if (is_callable($middlewareToBePiped)) {
$r = $this->getReflectionFunction($middlewareToBePiped);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use always meaningful names for variables. (loops are an exception)

But do we really need a reflection here? Smells like a hack.
A check of the interfaces and a simple method_exists is maybe enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been taken from zend-stratigility as a way of finding whether the middleware is a double-pass one, but I'll change it (it seemed like an over-complication to me, too).

Copy link
Member

@froschdesign froschdesign Sep 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been taken from zend-stratigility…

Ah, good to know.

it seemed like an over-complication to me, too

If the interface Interop\Http\ServerMiddleware\MiddlewareInterface is not present but the current middleware is callable, then there is also no check for the parameters.
And the decorator DoublePassMiddlewareDecorator includes also a test of the result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've applied changes. Now we check whether the callable is missing the process method or if it does not implement the Interop\Http\ServerMiddleware\MiddlewareInterface, then wraps it, using the decorator.

@froschdesign
Copy link
Member

Related to #290

if (is_callable($middlewareToBePiped)
&& (
! $middlewaresToBePiped instanceof MiddlewareInterface
|| ! method_exists($middlewaresToBePiped, 'process')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes should covered by unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new test testSuccessfullyDispatchesDoublePassMiddleware?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the test, but as I come to think about the if condition, doesn't it have to be x && !y && !z instead of x && (!y || !z).. the first one makes more sense than the second one. Otherwise middlewares that are not an instance of MiddlewareInterface, but have the process method would be decorated, as well. Hm...

Copy link
Member

@geerteltink geerteltink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been digging a bit deeper into the failed tests and this PR. What you are basically doing is decorating the middleware in the tests to prevent the deprecation notice from stratigility. Doing it this way it will prevent notices for users as well. By the time zend-mvc is updated to support stratigility 3.0 their applications are not working anymore and they never saw a notice.

I think the correct way is to actually fix the middleware listener tests.

public function testSuccessfullyDispatchesMiddleware()
{
$event = $this->createMvcEvent('path', function ($request, $response) {
$this->assertInstanceOf(ServerRequestInterface::class, $request);
$this->assertInstanceOf(ResponseInterface::class, $response);
$response->getBody()->write('Test!');
return $response;
});

As you can see that test uses the double pass middleware. This should be changed to use the PSR-12 Middleware interface:
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as PsrServerRequestInterface;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Psr\Http\Message\ResponseInterface is imported twice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was there before the changes, but I fixed it anyway.

@geerteltink
Copy link
Member

geerteltink commented Sep 13, 2018

To summarize the discussion we had last night on Slack:

  • Currently all zend-mvc latest tests fail because of a deprecation notice in stratigility 2.2. The notices are there for a reason and shouldn't be suppressed. See here and here.
  • Stratigility 3.0 uses PSR-15
  • Stratigility 2.2 has the DoublePassMiddlewareDecorator which is needed to properly suppress the deprecation notice.
  • Stratigility 2.1 has support for http-interop/http-middleware 0.5.0 via a polyfill.
  • Stratigility 2.0 has support for http-interop/http-middleware version to 0.4.1

zend-mvc is tested against stratigility ^2.0.1. The deprecation notices were added in 2.2.0.

Since stratigility 3 requires php ^7.1 and zend-mvc requires ^5.6 || ^7.0, support for PSR-15 is out of the question. We tried to make expressive 2 compatible with all different middleware interfaces and it became pretty messy.

I suggested this solution:

  1. Release a zend-mvc 2.7.16 hotfix that restricts stratigility in composer require-dev to "zendframework/zend-stratigility": ">=2.0.1 <2.2" and fix the tests.
  2. Release zend-mvc 2.8.0 with support for "zendframework/zend-stratigility": "^2.2.2" and use the DoublePassMiddlewareDecorator in the MiddlewareListenerTest to fix the current failing latest tests.

/cc @weierophinney

@froschdesign
Copy link
Member

@xtreamwayz
Sorry, maybe I missed something. But why 2.7. and 2.8?

@thexpand
Copy link
Contributor Author

The master branch is currently on 3.1.1, so the hotfix will be released as a new patch version 3.1.2 and then the update to support stratigility 2.2.2 will be released as a new minor version 3.2.0.

@weierophinney
Copy link
Member

I suggested this solution:

1. Release a zend-mvc `2.7.16` hotfix that restricts stratigility in composer require-dev to `"zendframework/zend-stratigility": ">=2.0.1 <2.2"` and fix the tests.

2. Release zend-mvc `2.8.0` with support for `"zendframework/zend-stratigility": "^2.2.2"` and use the `DoublePassMiddlewareDecorator` in the `MiddlewareListenerTest` to fix the current failing `latest` tests.

The v2 series of zend-mvc is no longer supported (see the LTS page for details). As such, we can ignore those versions entirely. Users will have to heed the notices and update their code accordingly.

For v3, the approach @thexpand outlines seems sensible.

@geerteltink
Copy link
Member

Sorry, maybe I missed something. But why 2.7. and 2.8?

No, I missed something... the zend-mvc 3 release :D

@boesing
Copy link
Member

boesing commented Sep 17, 2018

So I guess this can be closed in favor of #295?

@thexpand
Copy link
Contributor Author

thexpand commented Sep 17, 2018

@boesing This PR has nothing to do with #295
It is about providing support for stratigility 2.2.2.
As outlined above, this is the second step. The PR you are talking about is meant to only fix the failing tests.

@thexpand thexpand changed the title Hotfix - callable double pass middleware Provide support for zend-stratigility 2.2.2 Sep 17, 2018
@boesing
Copy link
Member

boesing commented Sep 17, 2018

@thexpand ah never mind, just saw the stratigility change and thought this was the the same composer change as in #295
So just ignore my comment.

@Xerkus
Copy link
Member

Xerkus commented Feb 7, 2019

I marked this PR as won't fix but will keep it open for now. Next week I will pull the stratigility support into satellite mvc package and reapply 2.2.2 changes there.

@Xerkus
Copy link
Member

Xerkus commented Feb 17, 2019

Alternative solution to be provided by #308

@Xerkus Xerkus closed this Feb 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants