diff --git a/.gitignore b/.gitignore index 55940e5..0d2007d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /vendor/ -composer.lock \ No newline at end of file +composer.lock +.idea \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 84c7bac..125ebe4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ language: php php: - - 5.6 - - 7.0 - 7.1 - - hhvm + - 7.2 + - 7.3 env: - DEPS=lowest diff --git a/README.md b/README.md index 29487fb..6c04c47 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Create instance of middleware as you want (we use [named constructors](http://ve ```php $date = DateTime::createFromFormat('Y-m-d H:i:s', '2025-11-30 11:12:13'); -$middleware = MaintenanceMiddleware::createWithRetryAsDateTime($date); +$middleware = MaintenanceMiddleware::createWithRetryAsDateTime($date, $psr17ResponseFactory); $middlewareRunner->add(middleware); $middlewareRunner->run(); @@ -28,4 +28,6 @@ Use composer! ```bash composer require php-middleware/maintenance -``` \ No newline at end of file +``` + +This package require [PSR-17 message factory](https://packagist.org/providers/psr/http-factory-implementation) implementation to return SEO friendly response. \ No newline at end of file diff --git a/composer.json b/composer.json index a66bf6c..e9fcd72 100644 --- a/composer.json +++ b/composer.json @@ -7,17 +7,21 @@ "middleware", "psr", "psr-7", - "maintenance" + "maintenance", + "psr-15", + "psr-17" ], "require": { - "php": ">=5.6", + "php": ">=7.1", + "psr/http-factory": "^1.0", + "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0", - "php-middleware/double-pass-compatibility": "^1.0", - "http-interop/http-middleware": "^0.4.1" + "psr/http-server-middleware": "^1.0", + "psr/http-server-handler": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^5.6 || ^6.1", - "zendframework/zend-diactoros": "^1.1.3" + "phpunit/phpunit": "^7.3", + "zendframework/zend-diactoros": "^2.0" }, "autoload": { "psr-4": { diff --git a/phpunit.xml b/phpunit.xml index 0344107..c52c8bb 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -2,7 +2,7 @@ - + ./test diff --git a/src/MaintenanceMiddleware.php b/src/MaintenanceMiddleware.php index c403de1..78702c6 100644 --- a/src/MaintenanceMiddleware.php +++ b/src/MaintenanceMiddleware.php @@ -4,17 +4,14 @@ use DateTime; use DateTimeInterface; -use Interop\Http\ServerMiddleware\DelegateInterface; -use Interop\Http\ServerMiddleware\MiddlewareInterface; -use InvalidArgumentException; -use PhpMiddleware\DoublePassCompatibilityTrait; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use Zend\Diactoros\Response; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface; -final class MaintenanceMiddleware implements MiddlewareInterface +final class MaintenanceMiddleware implements RequestHandlerInterface, MiddlewareInterface { - use DoublePassCompatibilityTrait; - /** * @var string */ @@ -24,89 +21,68 @@ final class MaintenanceMiddleware implements MiddlewareInterface * @var int */ private $refresh = 0; + private $responseFactory; - private function __construct() + private function __construct(ResponseFactoryInterface $responseFactory) { + $this->responseFactory = $responseFactory; } - /** - * @return self - */ - public static function create() + public static function create(ResponseFactoryInterface $responseFactory): self { - return new self(); + return new self($responseFactory); } - /** - * @param int $seconds - * - * @return self - */ - public static function createWithRetryAsSeconds($seconds) + public static function createWithRetryAsSeconds(int $seconds, ResponseFactoryInterface $responseFactory): self { - if (!is_int($seconds)) { - throw new InvalidArgumentException('Seconds must be integer'); - } - $instance = new self(); + $instance = new self($responseFactory); $instance->retryAfter = (string) $seconds; return $instance; } - /** - * @param int $seconds - * - * @return self - */ - public static function createWithRetryAsSecondsAndRefresh($seconds) + public static function createWithRetryAsSecondsAndRefresh(int $seconds, ResponseFactoryInterface $responseFactory): self { - $instance = self::createWithRetryAsSeconds($seconds); + $instance = self::createWithRetryAsSeconds($seconds, $responseFactory); $instance->refresh = $seconds; return $instance; } - /** - * @param DateTimeInterface $datetime - * - * @return self - */ - public static function createWithRetryAsDateTime(DateTimeInterface $datetime) + public static function createWithRetryAsDateTime(DateTimeInterface $datetime, ResponseFactoryInterface $responseFactory): self { - $instance = new self(); - + $instance = new self($responseFactory); $instance->retryAfter = $datetime->format(DateTime::RFC2822); return $instance; } - /** - * @param DateTimeInterface $datetime - * - * @return self - */ - public static function createWithRetryAsDateTimeAndRefresh(DateTimeInterface $datetime) + public static function createWithRetryAsDateTimeAndRefresh(DateTimeInterface $datetime, ResponseFactoryInterface $responseFactory) { - $instance = self::createWithRetryAsDateTime($datetime); + $instance = self::createWithRetryAsDateTime($datetime, $responseFactory); $diff = time() - $datetime->getTimestamp(); $instance->refresh = $diff; return $instance; } - public function process(ServerRequestInterface $request, DelegateInterface $delegate) + public function handle(ServerRequestInterface $request): ResponseInterface { - $headers = []; + $response = $this->responseFactory->createResponse(503); if ($this->retryAfter !== '') { - $headers['Retry-After'] = $this->retryAfter; + $response = $response->withHeader('Retry-After', $this->retryAfter); if ($this->refresh > 0) { - $headers['Refresh'] = (string) $this->refresh; + $response = $response->withHeader('Refresh', (string) $this->refresh); } } - return new Response('php://memory', 503, $headers); + return $response; } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + return $this->handle($request); + } } diff --git a/test/MaintenanceMiddlewareTest.php b/test/MaintenanceMiddlewareTest.php index 6375ba4..3d34c82 100644 --- a/test/MaintenanceMiddlewareTest.php +++ b/test/MaintenanceMiddlewareTest.php @@ -6,23 +6,47 @@ use Exception; use PhpMiddleware\Maintenance\MaintenanceMiddleware; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\RequestHandlerInterface; use Zend\Diactoros\Response; +use Zend\Diactoros\ResponseFactory; use Zend\Diactoros\ServerRequest; +use Zend\Diactoros\ServerRequestFactory; class MaintenanceMiddlewareTest extends TestCase { + private $request; + private $responseFactory; + + protected function setUp() + { + $this->request = new ServerRequest(); + $this->responseFactory = new ResponseFactory(); + } + public function testWithoutRetry() { - $request = new ServerRequest(); - $response = new Response(); + $middleware = MaintenanceMiddleware::create($this->responseFactory); - $middleware = MaintenanceMiddleware::create(); + $response = $middleware->handle($this->request); - $next = function() { - throw new Exception('Next should not be called'); + $this->assertSame(503, $response->getStatusCode()); + $this->assertSame('', $response->getHeaderLine('Retry-After')); + } + + public function testWithoutRetryAsMiddleware() + { + $middleware = MaintenanceMiddleware::create($this->responseFactory); + + $requestHandler = new class implements RequestHandlerInterface { + public function handle(ServerRequestInterface $request): ResponseInterface + { + return new Response(); + } }; - $response = $middleware->__invoke($request, $response, $next); + $response = $middleware->process($this->request, $requestHandler); $this->assertSame(503, $response->getStatusCode()); $this->assertSame('', $response->getHeaderLine('Retry-After')); @@ -30,16 +54,9 @@ public function testWithoutRetry() public function testWithRetryAsSeconds() { - $request = new ServerRequest(); - $response = new Response(); - - $middleware = MaintenanceMiddleware::createWithRetryAsSeconds(3600); + $middleware = MaintenanceMiddleware::createWithRetryAsSeconds(3600, $this->responseFactory); - $next = function() { - throw new Exception('Next should not be called'); - }; - - $response = $middleware->__invoke($request, $response, $next); + $response = $middleware->handle($this->request); $this->assertSame(503, $response->getStatusCode()); $this->assertSame('3600', $response->getHeaderLine('Retry-After')); @@ -48,16 +65,9 @@ public function testWithRetryAsSeconds() public function testWithRetryAsSecondsWithRefresh() { - $request = new ServerRequest(); - $response = new Response(); - - $middleware = MaintenanceMiddleware::createWithRetryAsSecondsAndRefresh(3600); + $middleware = MaintenanceMiddleware::createWithRetryAsSecondsAndRefresh(3600, $this->responseFactory); - $next = function() { - throw new Exception('Next should not be called'); - }; - - $response = $middleware->__invoke($request, $response, $next); + $response = $middleware->handle($this->request); $this->assertSame(503, $response->getStatusCode()); $this->assertSame('3600', $response->getHeaderLine('Retry-After')); @@ -66,18 +76,11 @@ public function testWithRetryAsSecondsWithRefresh() public function testWithRetryAsDatetime() { - $request = new ServerRequest(); - $response = new Response(); - $date = DateTime::createFromFormat('Y-m-d H:i:s', '2015-11-30 11:12:13'); - $middleware = MaintenanceMiddleware::createWithRetryAsDateTime($date); + $middleware = MaintenanceMiddleware::createWithRetryAsDateTime($date, $this->responseFactory); - $next = function() { - throw new Exception('Next should not be called'); - }; - - $response = $middleware->__invoke($request, $response, $next); + $response = $middleware->handle($this->request); $this->assertSame(503, $response->getStatusCode()); $this->assertSame('Mon, 30 Nov 2015 11:12:13 +0000', $response->getHeaderLine('Retry-After')); @@ -86,18 +89,11 @@ public function testWithRetryAsDatetime() public function testWithRetryAsDatetimeWithRefresh() { - $request = new ServerRequest(); - $response = new Response(); - $date = DateTime::createFromFormat('Y-m-d H:i:s', '2015-11-30 11:12:13'); - $middleware = MaintenanceMiddleware::createWithRetryAsDateTimeAndRefresh($date); - - $next = function() { - throw new Exception('Next should not be called'); - }; + $middleware = MaintenanceMiddleware::createWithRetryAsDateTimeAndRefresh($date, $this->responseFactory); - $response = $middleware->__invoke($request, $response, $next); + $response = $middleware->handle($this->request); $this->assertSame(503, $response->getStatusCode()); $this->assertSame('Mon, 30 Nov 2015 11:12:13 +0000', $response->getHeaderLine('Retry-After'));