diff --git a/.travis.yml b/.travis.yml
index 6e5357c0f..982179948 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,6 @@ branches:
- /.*/
php:
- - 7
- 7.1
- 7.2
@@ -16,12 +15,10 @@ before_install:
before_script:
- composer self-update
- composer install --no-interaction
- - if [[ $TRAVIS_PHP_VERSION = 7.1 ]] || [[ $TRAVIS_PHP_VERSION = 7.2 ]]; then composer global require --dev phpstan/phpstan:0.9.*; fi
script:
- mkdir build
- composer check
- - if [[ $TRAVIS_PHP_VERSION = 7.1 ]] || [[ $TRAVIS_PHP_VERSION = 7.2 ]]; then ~/.composer/vendor/bin/phpstan analyse module/*/src/ --level=6 -c phpstan.neon; fi
after_script:
- vendor/bin/phpcov merge build --clover build/clover.xml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d5b69cbd..114abffcb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
## CHANGELOG
+### 1.8.1
+
+**Features**
+
+* [125: Implement a path which returns a 1px image instead of a redirection](https://github.com/shlinkio/shlink/issues/125)
+
+**Enhancements:**
+
+* [130: Update to Expressive 3](https://github.com/shlinkio/shlink/issues/130)
+* [137: Update symfony packages to v4](https://github.com/shlinkio/shlink/issues/137)
+
+**Tasks**
+
+* [131: Drop support for PHP 7](https://github.com/shlinkio/shlink/issues/131)
+* [132: Add infection to improve tests](https://github.com/shlinkio/shlink/issues/132)
+
### 1.7.2
**Bugs:**
diff --git a/composer.json b/composer.json
index d961f5d5d..7fe311bb3 100644
--- a/composer.json
+++ b/composer.json
@@ -12,8 +12,8 @@
}
],
"require": {
- "php": "^7.0",
- "acelaya/ze-content-based-error-handler": "^2.0",
+ "php": "^7.1",
+ "acelaya/ze-content-based-error-handler": "^2.2",
"cocur/slugify": "^3.0",
"doctrine/annotations": "^1.4",
"doctrine/cache": "^1.6",
@@ -22,23 +22,23 @@
"doctrine/dbal": "^2.5",
"doctrine/migrations": "^1.4",
"doctrine/orm": "^2.5",
- "endroid/qrcode": "^1.7",
+ "endroid/qr-code": "^1.7",
"firebase/php-jwt": "^4.0",
"guzzlehttp/guzzle": "^6.2",
- "http-interop/http-middleware": "^0.4.1",
"mikehaertl/phpwkhtmltopdf": "^2.2",
"monolog/monolog": "^1.21",
"roave/security-advisories": "dev-master",
- "symfony/console": "^3.4",
- "symfony/filesystem": "^3.0",
- "symfony/process": "^3.0",
+ "symfony/console": "^4.0",
+ "symfony/filesystem": "^4.0",
+ "symfony/process": "^4.0",
"theorchard/monolog-cascade": "^0.4",
"zendframework/zend-config": "^3.0",
"zendframework/zend-config-aggregator": "^1.0",
- "zendframework/zend-expressive": "^2.0",
- "zendframework/zend-expressive-fastroute": "^2.0",
- "zendframework/zend-expressive-helpers": "^4.2",
- "zendframework/zend-expressive-platesrenderer": "^1.3",
+ "zendframework/zend-diactoros": "^1.7",
+ "zendframework/zend-expressive": "^3.0",
+ "zendframework/zend-expressive-fastroute": "^3.0",
+ "zendframework/zend-expressive-helpers": "^5.0",
+ "zendframework/zend-expressive-platesrenderer": "^2.0",
"zendframework/zend-i18n": "^2.7",
"zendframework/zend-inputfilter": "^2.8",
"zendframework/zend-paginator": "^2.6",
@@ -47,14 +47,16 @@
},
"require-dev": {
"filp/whoops": "^2.0",
- "phpunit/dbunit": "^3.0",
- "phpunit/phpcov": "^4.0",
- "phpunit/phpunit": "^6.0",
+ "infection/infection": "^0.8.1",
+ "phpstan/phpstan": "0.9",
+ "phpunit/phpcov": "^5.0",
+ "phpunit/phpunit": "^7.0",
"slevomat/coding-standard": "^4.0",
"squizlabs/php_codesniffer": "^3.1 <3.2",
- "symfony/dotenv": "^3.4",
- "symfony/var-dumper": "^3.0",
- "zendframework/zend-expressive-tooling": "^0.4"
+ "symfony/dotenv": "^4.0",
+ "symfony/var-dumper": "^4.0",
+ "zendframework/zend-component-installer": "^2.1",
+ "zendframework/zend-expressive-tooling": "^1.0"
},
"autoload": {
"psr-4": {
@@ -84,8 +86,10 @@
"scripts": {
"check": [
"@cs",
+ "@stan",
"@test",
- "@func-test"
+ "@func-test",
+ "@infect"
],
"cs": "phpcs",
"cs-fix": "phpcbf",
@@ -97,13 +101,17 @@
"@test",
"@func-test",
"phpcov merge build --html build/html"
- ]
+ ],
+ "stan": "phpstan analyse module/*/src/ --level=6 -c phpstan.neon",
+ "infect": "infection --threads=4 --min-msi=65 --only-covered --log-verbosity=2",
+ "infect-show": "infection --threads=4 --min-msi=65 --only-covered --log-verbosity=2 --show-mutations",
+ "expressive": "expressive"
},
"config": {
"process-timeout": 0,
"sort-packages": true,
"platform": {
- "php": "7.0.8"
+ "php": "7.1.8"
}
}
}
diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php
index 8afccea03..aa105e6d6 100644
--- a/config/autoload/dependencies.global.php
+++ b/config/autoload/dependencies.global.php
@@ -5,30 +5,23 @@
use Zend\Expressive;
use Zend\Expressive\Container;
use Zend\Expressive\Helper;
-use Zend\Expressive\Middleware;
-use Zend\Expressive\Plates;
-use Zend\Expressive\Router;
use Zend\Expressive\Router\Middleware\ImplicitOptionsMiddleware;
-use Zend\Expressive\Template;
use Zend\ServiceManager\Factory\InvokableFactory;
-use Zend\Stratigility\Middleware\ErrorHandler;
return [
'dependencies' => [
'factories' => [
- Expressive\Application::class => Container\ApplicationFactory::class,
- Template\TemplateRendererInterface::class => Plates\PlatesRendererFactory::class,
- Router\RouterInterface::class => Router\FastRouteRouterFactory::class,
- ErrorHandler::class => Container\ErrorHandlerFactory::class,
ImplicitOptionsMiddleware::class => EmptyResponseImplicitOptionsMiddlewareFactory::class,
Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
Helper\ServerUrlHelper::class => InvokableFactory::class,
],
- 'aliases' => [
- Middleware\ImplicitOptionsMiddleware::class => ImplicitOptionsMiddleware::class,
+ 'delegators' => [
+ Expressive\Application::class => [
+ Container\ApplicationConfigInjectionDelegator::class,
+ ],
],
],
diff --git a/config/autoload/middleware-pipeline.global.php b/config/autoload/middleware-pipeline.global.php
index 2d4c0c18d..dad75c139 100644
--- a/config/autoload/middleware-pipeline.global.php
+++ b/config/autoload/middleware-pipeline.global.php
@@ -2,6 +2,7 @@
declare(strict_types=1);
use Shlinkio\Shlink\Common\Middleware\LocaleMiddleware;
+use Shlinkio\Shlink\Core\Response\NotFoundDelegate;
use Shlinkio\Shlink\Rest\Middleware\BodyParserMiddleware;
use Shlinkio\Shlink\Rest\Middleware\CheckAuthenticationMiddleware;
use Shlinkio\Shlink\Rest\Middleware\CrossDomainMiddleware;
@@ -48,6 +49,7 @@
'post-routing' => [
'middleware' => [
Expressive\Router\Middleware\DispatchMiddleware::class,
+ NotFoundDelegate::class,
],
'priority' => 1,
],
diff --git a/config/config.php b/config/config.php
index 28ad33348..d7ec97e90 100644
--- a/config/config.php
+++ b/config/config.php
@@ -7,6 +7,7 @@
use Shlinkio\Shlink\Core;
use Shlinkio\Shlink\Rest;
use Zend\ConfigAggregator;
+use Zend\Expressive;
/**
* Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``.
@@ -18,8 +19,11 @@
*/
return (new ConfigAggregator\ConfigAggregator([
- Zend\Expressive\ConfigProvider::class,
- Zend\Expressive\Router\ConfigProvider::class,
+ Expressive\ConfigProvider::class,
+ Expressive\Router\ConfigProvider::class,
+ Expressive\Router\FastRouteRouter\ConfigProvider::class,
+ Expressive\Plates\ConfigProvider::class,
+ Expressive\Helper\ConfigProvider::class,
ExpressiveErrorHandler\ConfigProvider::class,
Common\ConfigProvider::class,
Core\ConfigProvider::class,
diff --git a/infection.json b/infection.json
new file mode 100644
index 000000000..5f5fb65bf
--- /dev/null
+++ b/infection.json
@@ -0,0 +1,18 @@
+{
+ "source": {
+ "directories": [
+ "module/*/src"
+ ],
+ "excludes": []
+ },
+ "timeout": 10,
+ "logs": {
+ "text": "build/infection/infection-log.txt",
+ "summary": "build/infection/summary-log.txt",
+ "debug": "build/infection/debug-log.txt"
+ },
+ "tmpDir": "build/infection/temp",
+ "phpUnit": {
+ "configDir": "."
+ }
+}
diff --git a/module/CLI/src/Command/Install/InstallCommand.php b/module/CLI/src/Command/Install/InstallCommand.php
index ef08b460c..06f1be930 100644
--- a/module/CLI/src/Command/Install/InstallCommand.php
+++ b/module/CLI/src/Command/Install/InstallCommand.php
@@ -134,7 +134,7 @@ public function execute(InputInterface $input, OutputInterface $output)
if (! $this->isUpdate) {
$this->io->write('Initializing database...');
if (! $this->runCommand(
- 'php vendor/bin/doctrine.php orm:schema-tool:create',
+ 'php vendor/bin/doctrine orm:schema-tool:create',
'Error generating database.',
$output
)) {
@@ -155,7 +155,7 @@ public function execute(InputInterface $input, OutputInterface $output)
// Generate proxies
$this->io->write('Generating proxies...');
if (! $this->runCommand(
- 'php vendor/bin/doctrine.php orm:generate-proxies',
+ 'php vendor/bin/doctrine orm:generate-proxies',
'Error generating proxies.',
$output
)) {
diff --git a/module/Common/src/Factory/EmptyResponseImplicitOptionsMiddlewareFactory.php b/module/Common/src/Factory/EmptyResponseImplicitOptionsMiddlewareFactory.php
index 89858e8c0..4371bb6b8 100644
--- a/module/Common/src/Factory/EmptyResponseImplicitOptionsMiddlewareFactory.php
+++ b/module/Common/src/Factory/EmptyResponseImplicitOptionsMiddlewareFactory.php
@@ -27,6 +27,8 @@ class EmptyResponseImplicitOptionsMiddlewareFactory implements FactoryInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
- return new ImplicitOptionsMiddleware(new EmptyResponse());
+ return new ImplicitOptionsMiddleware(function () {
+ return new EmptyResponse();
+ });
}
}
diff --git a/module/Common/src/Middleware/LocaleMiddleware.php b/module/Common/src/Middleware/LocaleMiddleware.php
index 1c48c863c..cdb5df196 100644
--- a/module/Common/src/Middleware/LocaleMiddleware.php
+++ b/module/Common/src/Middleware/LocaleMiddleware.php
@@ -3,10 +3,10 @@
namespace Shlinkio\Shlink\Common\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface as DelegateInterface;
use Zend\I18n\Translator\Translator;
class LocaleMiddleware implements MiddlewareInterface
@@ -32,15 +32,15 @@ public function __construct(Translator $translator)
*
* @return Response
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, DelegateInterface $delegate): Response
{
if (! $request->hasHeader('Accept-Language')) {
- return $delegate->process($request);
+ return $delegate->handle($request);
}
$locale = $request->getHeaderLine('Accept-Language');
$this->translator->setLocale($this->normalizeLocale($locale));
- return $delegate->process($request);
+ return $delegate->handle($request);
}
/**
diff --git a/module/Common/src/Response/PixelResponse.php b/module/Common/src/Response/PixelResponse.php
new file mode 100644
index 000000000..a19c1c85c
--- /dev/null
+++ b/module/Common/src/Response/PixelResponse.php
@@ -0,0 +1,33 @@
+createBody(), $status, $headers);
+ }
+
+ /**
+ * Create the message body.
+ *
+ * @return StreamInterface
+ */
+ private function createBody(): StreamInterface
+ {
+ $body = new Stream('php://temp', 'wb+');
+ $body->write(\base64_decode(self::BASE_64_IMAGE));
+ $body->rewind();
+ return $body;
+ }
+}
diff --git a/module/Common/test-func/DbUnit/DatabaseTestCase.php b/module/Common/test-func/DbUnit/DatabaseTestCase.php
index 58a10bdc3..89ee871f0 100644
--- a/module/Common/test-func/DbUnit/DatabaseTestCase.php
+++ b/module/Common/test-func/DbUnit/DatabaseTestCase.php
@@ -3,40 +3,17 @@
namespace ShlinkioTest\Shlink\Common\DbUnit;
-use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\ORM\EntityManagerInterface;
-use PHPUnit\DbUnit\Database\Connection as DbConn;
-use PHPUnit\DbUnit\DataSet\IDataSet as DataSet;
-use PHPUnit\DbUnit\TestCase;
+use PHPUnit\Framework\TestCase;
abstract class DatabaseTestCase extends TestCase
{
- const ENTITIES_TO_EMPTY = [];
+ protected const ENTITIES_TO_EMPTY = [];
/**
* @var EntityManagerInterface
*/
public static $em;
- /**
- * @var DbConn
- */
- private static $conn;
-
- public function getConnection(): DbConn
- {
- if (isset(self::$conn)) {
- return self::$conn;
- }
-
- /** @var PDOConnection $pdo */
- $pdo = static::$em->getConnection()->getWrappedConnection();
- return self::$conn = $this->createDefaultDBConnection($pdo, static::$em->getConnection()->getDatabase());
- }
-
- public function getDataSet(): DataSet
- {
- return $this->createArrayDataSet([]);
- }
protected function getEntityManager(): EntityManagerInterface
{
diff --git a/module/Common/test/Factory/EmptyResponseImplicitOptionsMiddlewareFactoryTest.php b/module/Common/test/Factory/EmptyResponseImplicitOptionsMiddlewareFactoryTest.php
index 11b76440c..8e6b17b76 100644
--- a/module/Common/test/Factory/EmptyResponseImplicitOptionsMiddlewareFactoryTest.php
+++ b/module/Common/test/Factory/EmptyResponseImplicitOptionsMiddlewareFactoryTest.php
@@ -38,8 +38,8 @@ public function responsePrototypeIsEmptyResponse()
$instance = $this->factory->__invoke(new ServiceManager(), '');
$ref = new \ReflectionObject($instance);
- $prop = $ref->getProperty('response');
+ $prop = $ref->getProperty('responseFactory');
$prop->setAccessible(true);
- $this->assertInstanceOf(EmptyResponse::class, $prop->getValue($instance));
+ $this->assertInstanceOf(EmptyResponse::class, $prop->getValue($instance)());
}
}
diff --git a/module/Common/test/Middleware/LocaleMiddlewareTest.php b/module/Common/test/Middleware/LocaleMiddlewareTest.php
index 703ef7000..35b6aa3ae 100644
--- a/module/Common/test/Middleware/LocaleMiddlewareTest.php
+++ b/module/Common/test/Middleware/LocaleMiddlewareTest.php
@@ -32,7 +32,7 @@ public function setUp()
public function whenNoHeaderIsPresentLocaleIsNotChanged()
{
$this->assertEquals('ru', $this->translator->getLocale());
- $this->middleware->process(ServerRequestFactory::fromGlobals(), TestUtils::createDelegateMock()->reveal());
+ $this->middleware->process(ServerRequestFactory::fromGlobals(), TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals('ru', $this->translator->getLocale());
}
@@ -43,7 +43,7 @@ public function whenTheHeaderIsPresentLocaleIsChanged()
{
$this->assertEquals('ru', $this->translator->getLocale());
$request = ServerRequestFactory::fromGlobals()->withHeader('Accept-Language', 'es');
- $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
+ $this->middleware->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals('es', $this->translator->getLocale());
}
@@ -52,7 +52,7 @@ public function whenTheHeaderIsPresentLocaleIsChanged()
*/
public function localeGetsNormalized()
{
- $delegate = TestUtils::createDelegateMock();
+ $delegate = TestUtils::createReqHandlerMock();
$this->assertEquals('ru', $this->translator->getLocale());
diff --git a/module/Common/test/Util/TestUtils.php b/module/Common/test/Util/TestUtils.php
index 075498d29..64ed655ab 100644
--- a/module/Common/test/Util/TestUtils.php
+++ b/module/Common/test/Util/TestUtils.php
@@ -3,22 +3,22 @@
namespace ShlinkioTest\Shlink\Common\Util;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Prophecy\Argument;
use Prophecy\Prophet;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response;
class TestUtils
{
private static $prophet;
- public static function createDelegateMock(ResponseInterface $response = null, RequestInterface $request = null)
+ public static function createReqHandlerMock(ResponseInterface $response = null, RequestInterface $request = null)
{
$argument = $request ?: Argument::any();
- $delegate = static::getProphet()->prophesize(DelegateInterface::class);
- $delegate->process($argument)->willReturn($response ?: new Response());
+ $delegate = static::getProphet()->prophesize(RequestHandlerInterface::class);
+ $delegate->handle($argument)->willReturn($response ?: new Response());
return $delegate;
}
diff --git a/module/Core/config/dependencies.config.php b/module/Core/config/dependencies.config.php
index 11038e4b0..9061a3f5e 100644
--- a/module/Core/config/dependencies.config.php
+++ b/module/Core/config/dependencies.config.php
@@ -28,6 +28,7 @@
// Middleware
Action\RedirectAction::class => ConfigAbstractFactory::class,
+ Action\PixelAction::class => ConfigAbstractFactory::class,
Action\QrCodeAction::class => ConfigAbstractFactory::class,
Action\PreviewAction::class => ConfigAbstractFactory::class,
Middleware\QrCodeCacheMiddleware::class => ConfigAbstractFactory::class,
@@ -60,6 +61,11 @@
Service\VisitsTracker::class,
Options\AppOptions::class,
],
+ Action\PixelAction::class => [
+ Service\UrlShortener::class,
+ Service\VisitsTracker::class,
+ Options\AppOptions::class,
+ ],
Action\QrCodeAction::class => [RouterInterface::class, Service\UrlShortener::class, 'Logger_Shlink'],
Action\PreviewAction::class => [PreviewGenerator::class, Service\UrlShortener::class],
Middleware\QrCodeCacheMiddleware::class => [Cache::class],
diff --git a/module/Core/config/routes.config.php b/module/Core/config/routes.config.php
index e18cb4485..2d8c80b37 100644
--- a/module/Core/config/routes.config.php
+++ b/module/Core/config/routes.config.php
@@ -13,6 +13,12 @@
'middleware' => Action\RedirectAction::class,
'allowed_methods' => ['GET'],
],
+ [
+ 'name' => 'pixel-tracking',
+ 'path' => '/{shortCode}/track',
+ 'middleware' => Action\PixelAction::class,
+ 'allowed_methods' => ['GET'],
+ ],
[
'name' => 'short-url-qr-code',
'path' => '/{shortCode}/qr-code[/{size:[0-9]+}]',
diff --git a/module/Core/src/Action/AbstractTrackingAction.php b/module/Core/src/Action/AbstractTrackingAction.php
new file mode 100644
index 000000000..0ee475dbe
--- /dev/null
+++ b/module/Core/src/Action/AbstractTrackingAction.php
@@ -0,0 +1,74 @@
+urlShortener = $urlShortener;
+ $this->visitTracker = $visitTracker;
+ $this->appOptions = $appOptions;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * to the next middleware component to create the response.
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ *
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ $shortCode = $request->getAttribute('shortCode', '');
+ $query = $request->getQueryParams();
+ $disableTrackParam = $this->appOptions->getDisableTrackParam();
+
+ try {
+ $longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
+
+ // Track visit to this short code
+ if ($disableTrackParam === null || ! \array_key_exists($disableTrackParam, $query)) {
+ $this->visitTracker->track($shortCode, $request);
+ }
+
+ return $this->createResp($longUrl);
+ } catch (InvalidShortCodeException | EntityDoesNotExistException $e) {
+ return $this->buildErrorResponse($request, $handler);
+ }
+ }
+
+ abstract protected function createResp(string $longUrl): ResponseInterface;
+}
diff --git a/module/Core/src/Action/PixelAction.php b/module/Core/src/Action/PixelAction.php
new file mode 100644
index 000000000..5f2c797ae
--- /dev/null
+++ b/module/Core/src/Action/PixelAction.php
@@ -0,0 +1,15 @@
+getAttribute('shortCode');
@@ -52,12 +52,8 @@ public function process(Request $request, DelegateInterface $delegate)
$url = $this->urlShortener->shortCodeToUrl($shortCode);
$imagePath = $this->previewGenerator->generatePreview($url);
return $this->generateImageResponse($imagePath);
- } catch (InvalidShortCodeException $e) {
- return $this->buildErrorResponse($request, $delegate);
- } catch (EntityDoesNotExistException $e) {
- return $this->buildErrorResponse($request, $delegate);
- } catch (PreviewGenerationException $e) {
- return $this->buildErrorResponse($request, $delegate);
+ } catch (InvalidShortCodeException | EntityDoesNotExistException | PreviewGenerationException $e) {
+ return $this->buildErrorResponse($request, $handler);
}
}
}
diff --git a/module/Core/src/Action/QrCodeAction.php b/module/Core/src/Action/QrCodeAction.php
index 303636191..3e5aeaf92 100644
--- a/module/Core/src/Action/QrCodeAction.php
+++ b/module/Core/src/Action/QrCodeAction.php
@@ -4,10 +4,10 @@
namespace Shlinkio\Shlink\Core\Action;
use Endroid\QrCode\QrCode;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
@@ -49,11 +49,11 @@ public function __construct(
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
// Make sure the short URL exists for this short code
$shortCode = $request->getAttribute('shortCode');
@@ -61,10 +61,10 @@ public function process(Request $request, DelegateInterface $delegate)
$this->urlShortener->shortCodeToUrl($shortCode);
} catch (InvalidShortCodeException $e) {
$this->logger->warning('Tried to create a QR code with an invalid short code' . PHP_EOL . $e);
- return $this->buildErrorResponse($request, $delegate);
+ return $this->buildErrorResponse($request, $handler);
} catch (EntityDoesNotExistException $e) {
$this->logger->warning('Tried to create a QR code with a not found short code' . PHP_EOL . $e);
- return $this->buildErrorResponse($request, $delegate);
+ return $this->buildErrorResponse($request, $handler);
}
$path = $this->router->generateUri('long-url-redirect', ['shortCode' => $shortCode]);
@@ -80,7 +80,7 @@ public function process(Request $request, DelegateInterface $delegate)
* @param Request $request
* @return int
*/
- protected function getSizeParam(Request $request)
+ private function getSizeParam(Request $request): int
{
$size = (int) $request->getAttribute('size', 300);
if ($size < 50) {
diff --git a/module/Core/src/Action/RedirectAction.php b/module/Core/src/Action/RedirectAction.php
index e7702dde8..4654e1fe4 100644
--- a/module/Core/src/Action/RedirectAction.php
+++ b/module/Core/src/Action/RedirectAction.php
@@ -3,75 +3,15 @@
namespace Shlinkio\Shlink\Core\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
-use Psr\Http\Message\ServerRequestInterface as Request;
-use Shlinkio\Shlink\Core\Action\Util\ErrorResponseBuilderTrait;
-use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
-use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
-use Shlinkio\Shlink\Core\Options\AppOptions;
-use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
-use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
use Zend\Diactoros\Response\RedirectResponse;
-class RedirectAction implements MiddlewareInterface
+class RedirectAction extends AbstractTrackingAction
{
- use ErrorResponseBuilderTrait;
-
- /**
- * @var UrlShortenerInterface
- */
- private $urlShortener;
- /**
- * @var VisitsTrackerInterface
- */
- private $visitTracker;
- /**
- * @var AppOptions
- */
- private $appOptions;
-
- public function __construct(
- UrlShortenerInterface $urlShortener,
- VisitsTrackerInterface $visitTracker,
- AppOptions $appOptions
- ) {
- $this->urlShortener = $urlShortener;
- $this->visitTracker = $visitTracker;
- $this->appOptions = $appOptions;
- }
-
- /**
- * Process an incoming server request and return a response, optionally delegating
- * to the next middleware component to create the response.
- *
- * @param Request $request
- * @param DelegateInterface $delegate
- *
- * @return Response
- */
- public function process(Request $request, DelegateInterface $delegate)
+ protected function createResp(string $longUrl): Response
{
- $shortCode = $request->getAttribute('shortCode', '');
- $query = $request->getQueryParams();
- $disableTrackParam = $this->appOptions->getDisableTrackParam();
-
- try {
- $longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
-
- // Track visit to this short code
- if ($disableTrackParam === null || ! \array_key_exists($disableTrackParam, $query)) {
- $this->visitTracker->track($shortCode, $request);
- }
-
- // Return a redirect response to the long URL.
- // Use a temporary redirect to make sure browsers always hit the server for analytics purposes
- return new RedirectResponse($longUrl);
- } catch (InvalidShortCodeException $e) {
- return $this->buildErrorResponse($request, $delegate);
- } catch (EntityDoesNotExistException $e) {
- return $this->buildErrorResponse($request, $delegate);
- }
+ // Return a redirect response to the long URL.
+ // Use a temporary redirect to make sure browsers always hit the server for analytics purposes
+ return new RedirectResponse($longUrl);
}
}
diff --git a/module/Core/src/Action/Util/ErrorResponseBuilderTrait.php b/module/Core/src/Action/Util/ErrorResponseBuilderTrait.php
index 57380b8b3..efd0bc2ad 100644
--- a/module/Core/src/Action/Util/ErrorResponseBuilderTrait.php
+++ b/module/Core/src/Action/Util/ErrorResponseBuilderTrait.php
@@ -3,16 +3,18 @@
namespace Shlinkio\Shlink\Core\Action\Util;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Response\NotFoundDelegate;
trait ErrorResponseBuilderTrait
{
- private function buildErrorResponse(ServerRequestInterface $request, DelegateInterface $delegate): ResponseInterface
- {
+ private function buildErrorResponse(
+ ServerRequestInterface $request,
+ RequestHandlerInterface $handler
+ ): ResponseInterface {
$request = $request->withAttribute(NotFoundDelegate::NOT_FOUND_TEMPLATE, 'ShlinkCore::invalid-short-code');
- return $delegate->process($request);
+ return $handler->handle($request);
}
}
diff --git a/module/Core/src/Entity/Visit.php b/module/Core/src/Entity/Visit.php
index 5f67f636d..48edfb11c 100644
--- a/module/Core/src/Entity/Visit.php
+++ b/module/Core/src/Entity/Visit.php
@@ -57,7 +57,7 @@ public function __construct()
/**
* @return string
*/
- public function getReferer()
+ public function getReferer(): string
{
return $this->referer;
}
@@ -66,7 +66,7 @@ public function getReferer()
* @param string $referer
* @return $this
*/
- public function setReferer($referer)
+ public function setReferer($referer): self
{
$this->referer = $referer;
return $this;
@@ -75,7 +75,7 @@ public function setReferer($referer)
/**
* @return \DateTime
*/
- public function getDate()
+ public function getDate(): \DateTime
{
return $this->date;
}
@@ -84,7 +84,7 @@ public function getDate()
* @param \DateTime $date
* @return $this
*/
- public function setDate($date)
+ public function setDate($date): self
{
$this->date = $date;
return $this;
@@ -93,7 +93,7 @@ public function setDate($date)
/**
* @return ShortUrl
*/
- public function getShortUrl()
+ public function getShortUrl(): ShortUrl
{
return $this->shortUrl;
}
@@ -102,7 +102,7 @@ public function getShortUrl()
* @param ShortUrl $shortUrl
* @return $this
*/
- public function setShortUrl($shortUrl)
+ public function setShortUrl($shortUrl): self
{
$this->shortUrl = $shortUrl;
return $this;
@@ -111,7 +111,7 @@ public function setShortUrl($shortUrl)
/**
* @return string
*/
- public function getRemoteAddr()
+ public function getRemoteAddr(): string
{
return $this->remoteAddr;
}
@@ -120,7 +120,7 @@ public function getRemoteAddr()
* @param string $remoteAddr
* @return $this
*/
- public function setRemoteAddr($remoteAddr)
+ public function setRemoteAddr($remoteAddr): self
{
$this->remoteAddr = $remoteAddr;
return $this;
@@ -129,7 +129,7 @@ public function setRemoteAddr($remoteAddr)
/**
* @return string
*/
- public function getUserAgent()
+ public function getUserAgent(): string
{
return $this->userAgent;
}
@@ -138,7 +138,7 @@ public function getUserAgent()
* @param string $userAgent
* @return $this
*/
- public function setUserAgent($userAgent)
+ public function setUserAgent($userAgent): self
{
$this->userAgent = $userAgent;
return $this;
@@ -147,7 +147,7 @@ public function setUserAgent($userAgent)
/**
* @return VisitLocation
*/
- public function getVisitLocation()
+ public function getVisitLocation(): VisitLocation
{
return $this->visitLocation;
}
@@ -156,7 +156,7 @@ public function getVisitLocation()
* @param VisitLocation $visitLocation
* @return $this
*/
- public function setVisitLocation($visitLocation)
+ public function setVisitLocation($visitLocation): self
{
$this->visitLocation = $visitLocation;
return $this;
@@ -165,11 +165,11 @@ public function setVisitLocation($visitLocation)
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
- * @return mixed data which can be serialized by json_encode,
+ * @return array data which can be serialized by json_encode,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
- public function jsonSerialize()
+ public function jsonSerialize(): array
{
return [
'referer' => $this->referer,
diff --git a/module/Core/src/Middleware/QrCodeCacheMiddleware.php b/module/Core/src/Middleware/QrCodeCacheMiddleware.php
index e91ebd5ea..2f8bafe81 100644
--- a/module/Core/src/Middleware/QrCodeCacheMiddleware.php
+++ b/module/Core/src/Middleware/QrCodeCacheMiddleware.php
@@ -4,10 +4,10 @@
namespace Shlinkio\Shlink\Core\Middleware;
use Doctrine\Common\Cache\Cache;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response as DiactResp;
class QrCodeCacheMiddleware implements MiddlewareInterface
@@ -27,11 +27,11 @@ public function __construct(Cache $cache)
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
$cacheKey = $request->getUri()->getPath();
@@ -45,7 +45,7 @@ public function process(Request $request, DelegateInterface $delegate)
// If not, call the next middleware and cache it
/** @var Response $resp */
- $resp = $delegate->process($request);
+ $resp = $handler->handle($request);
$this->cache->save($cacheKey, [
'body' => $resp->getBody()->__toString(),
'content-type' => $resp->getHeaderLine('Content-Type'),
diff --git a/module/Core/src/Response/NotFoundDelegate.php b/module/Core/src/Response/NotFoundDelegate.php
index abe5f06ae..db5ab040f 100644
--- a/module/Core/src/Response/NotFoundDelegate.php
+++ b/module/Core/src/Response/NotFoundDelegate.php
@@ -4,9 +4,9 @@
namespace Shlinkio\Shlink\Core\Response;
use Fig\Http\Message\StatusCodeInterface;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface as DelegateInterface;
use Zend\Diactoros\Response;
use Zend\Expressive\Template\TemplateRendererInterface;
@@ -37,14 +37,14 @@ public function __construct(TemplateRendererInterface $renderer, string $default
* @return ResponseInterface
* @throws \InvalidArgumentException
*/
- public function process(ServerRequestInterface $request): ResponseInterface
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
- $accepts = explode(',', $request->getHeaderLine('Accept'));
- $accept = array_shift($accepts);
+ $accepts = \explode(',', $request->getHeaderLine('Accept'));
+ $accept = \array_shift($accepts);
$status = StatusCodeInterface::STATUS_NOT_FOUND;
// If the first accepted type is json, return a json response
- if (in_array($accept, ['application/json', 'text/json', 'application/x-json'], true)) {
+ if (\in_array($accept, ['application/json', 'text/json', 'application/x-json'], true)) {
return new Response\JsonResponse([
'error' => 'NOT_FOUND',
'message' => 'Not found',
diff --git a/module/Core/src/Util/TagManagerTrait.php b/module/Core/src/Util/TagManagerTrait.php
index 2d1b3d6c0..d93664639 100644
--- a/module/Core/src/Util/TagManagerTrait.php
+++ b/module/Core/src/Util/TagManagerTrait.php
@@ -14,7 +14,7 @@ trait TagManagerTrait
* @param string[] $tags
* @return Collections\Collection|Tag[]
*/
- protected function tagNamesToEntities(EntityManagerInterface $em, array $tags)
+ private function tagNamesToEntities(EntityManagerInterface $em, array $tags)
{
$entities = [];
foreach ($tags as $tagName) {
@@ -33,8 +33,8 @@ protected function tagNamesToEntities(EntityManagerInterface $em, array $tags)
* @param string $tagName
* @return string
*/
- protected function normalizeTagName($tagName)
+ private function normalizeTagName($tagName): string
{
- return str_replace(' ', '-', strtolower(trim($tagName)));
+ return \str_replace(' ', '-', \strtolower(\trim($tagName)));
}
}
diff --git a/module/Core/src/Validation/InputFactoryTrait.php b/module/Core/src/Validation/InputFactoryTrait.php
index 289c54e2b..4e5146944 100644
--- a/module/Core/src/Validation/InputFactoryTrait.php
+++ b/module/Core/src/Validation/InputFactoryTrait.php
@@ -9,7 +9,7 @@
trait InputFactoryTrait
{
- public function createInput($name, $required = true): Input
+ private function createInput($name, $required = true): Input
{
$input = new Input($name);
$input->setRequired($required)
diff --git a/module/Core/test/Action/PixelActionTest.php b/module/Core/test/Action/PixelActionTest.php
new file mode 100644
index 000000000..1a7f72967
--- /dev/null
+++ b/module/Core/test/Action/PixelActionTest.php
@@ -0,0 +1,63 @@
+urlShortener = $this->prophesize(UrlShortener::class);
+ $this->visitTracker = $this->prophesize(VisitsTracker::class);
+
+ $this->action = new PixelAction(
+ $this->urlShortener->reveal(),
+ $this->visitTracker->reveal(),
+ new AppOptions()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function imageIsReturned()
+ {
+ $shortCode = 'abc123';
+ $this->urlShortener->shortCodeToUrl($shortCode)->willReturn('http://domain.com/foo/bar')
+ ->shouldBeCalledTimes(1);
+ $this->visitTracker->track(Argument::cetera())->willReturn(null)
+ ->shouldBeCalledTimes(1);
+
+ $request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
+ $response = $this->action->process($request, TestUtils::createReqHandlerMock()->reveal());
+
+ $this->assertInstanceOf(PixelResponse::class, $response);
+ $this->assertEquals(200, $response->getStatusCode());
+ $this->assertEquals('image/gif', $response->getHeaderLine('content-type'));
+ }
+}
diff --git a/module/Core/test/Action/PreviewActionTest.php b/module/Core/test/Action/PreviewActionTest.php
index 8817eaa4d..abd4dc35d 100644
--- a/module/Core/test/Action/PreviewActionTest.php
+++ b/module/Core/test/Action/PreviewActionTest.php
@@ -3,11 +3,11 @@
namespace ShlinkioTest\Shlink\Core\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Common\Service\PreviewGenerator;
use Shlinkio\Shlink\Core\Action\PreviewAction;
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
@@ -47,8 +47,8 @@ public function invalidShortCodeFallsBackToNextMiddleware()
$shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode)->willThrow(EntityDoesNotExistException::class)
->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
- $delegate->process(Argument::cetera())->shouldBeCalledTimes(1)
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $delegate->handle(Argument::cetera())->shouldBeCalledTimes(1)
->willReturn(new Response());
$this->action->process(
@@ -70,7 +70,7 @@ public function correctShortCodeReturnsImageResponse()
$resp = $this->action->process(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
- TestUtils::createDelegateMock()->reveal()
+ TestUtils::createReqHandlerMock()->reveal()
);
$this->assertEquals(filesize($path), $resp->getHeaderLine('Content-length'));
@@ -85,9 +85,9 @@ public function invalidShortCodeExceptionFallsBackToNextMiddleware()
$shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode)->willThrow(InvalidShortCodeException::class)
->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process(Argument::any())->willReturn(new Response());
+ $process = $delegate->handle(Argument::any())->willReturn(new Response());
$this->action->process(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php
index c071ef7e9..2d58c8c9b 100644
--- a/module/Core/test/Action/QrCodeActionTest.php
+++ b/module/Core/test/Action/QrCodeActionTest.php
@@ -3,11 +3,11 @@
namespace ShlinkioTest\Shlink\Core\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
use Shlinkio\Shlink\Core\Action\QrCodeAction;
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
@@ -46,8 +46,8 @@ public function aNotFoundShortCodeWillDelegateIntoNextMiddleware()
$shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode)->willThrow(EntityDoesNotExistException::class)
->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
- $process = $delegate->process(Argument::any())->willReturn(new Response());
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $process = $delegate->handle(Argument::any())->willReturn(new Response());
$this->action->process(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
@@ -65,9 +65,9 @@ public function anInvalidShortCodeWillReturnNotFoundResponse()
$shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode)->willThrow(InvalidShortCodeException::class)
->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process(Argument::any())->willReturn(new Response());
+ $process = $delegate->handle(Argument::any())->willReturn(new Response());
$this->action->process(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
@@ -84,7 +84,7 @@ public function aCorrectRequestReturnsTheQrCodeResponse()
{
$shortCode = 'abc123';
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn('')->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
$resp = $this->action->process(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
@@ -93,6 +93,6 @@ public function aCorrectRequestReturnsTheQrCodeResponse()
$this->assertInstanceOf(QrCodeResponse::class, $resp);
$this->assertEquals(200, $resp->getStatusCode());
- $delegate->process(Argument::any())->shouldHaveBeenCalledTimes(0);
+ $delegate->handle(Argument::any())->shouldHaveBeenCalledTimes(0);
}
}
diff --git a/module/Core/test/Action/RedirectActionTest.php b/module/Core/test/Action/RedirectActionTest.php
index ed37baaef..88b44d074 100644
--- a/module/Core/test/Action/RedirectActionTest.php
+++ b/module/Core/test/Action/RedirectActionTest.php
@@ -3,11 +3,11 @@
namespace ShlinkioTest\Shlink\Core\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Action\RedirectAction;
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
use Shlinkio\Shlink\Core\Options\AppOptions;
@@ -57,7 +57,7 @@ public function redirectionIsPerformedToLongUrl()
->shouldBeCalledTimes(1);
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertInstanceOf(Response\RedirectResponse::class, $response);
$this->assertEquals(302, $response->getStatusCode());
@@ -76,9 +76,9 @@ public function nextMiddlewareIsInvokedIfLongUrlIsNotFound()
$this->visitTracker->track(Argument::cetera())->willReturn(null)
->shouldNotBeCalled();
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process(Argument::any())->willReturn(new Response());
+ $process = $delegate->handle(Argument::any())->willReturn(new Response());
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
$this->action->process($request, $delegate->reveal());
@@ -100,7 +100,7 @@ public function visitIsNotTrackedIfDisableParamIsProvided()
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode)
->withQueryParams(['foobar' => true]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertInstanceOf(Response\RedirectResponse::class, $response);
$this->assertEquals(302, $response->getStatusCode());
diff --git a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php b/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php
index 5b173f68d..f566a6bfc 100644
--- a/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php
+++ b/module/Core/test/Middleware/QrCodeCacheMiddlewareTest.php
@@ -5,9 +5,9 @@
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\Cache;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Middleware\QrCodeCacheMiddleware;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
@@ -35,8 +35,8 @@ public function setUp()
*/
public function noCachedPathFallsBackToNextMiddleware()
{
- $delegate = $this->prophesize(DelegateInterface::class);
- $delegate->process(Argument::any())->willReturn(new Response())->shouldBeCalledTimes(1);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $delegate->handle(Argument::any())->willReturn(new Response())->shouldBeCalledTimes(1);
$this->middleware->process(ServerRequestFactory::fromGlobals()->withUri(
new Uri('/foo/bar')
@@ -53,7 +53,7 @@ public function cachedPathReturnsCacheContent()
$isCalled = false;
$uri = (new Uri())->withPath('/foo');
$this->cache->save('/foo', ['body' => 'the body', 'content-type' => 'image/png']);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
$resp = $this->middleware->process(
ServerRequestFactory::fromGlobals()->withUri($uri),
@@ -64,6 +64,6 @@ public function cachedPathReturnsCacheContent()
$resp->getBody()->rewind();
$this->assertEquals('the body', $resp->getBody()->getContents());
$this->assertEquals('image/png', $resp->getHeaderLine('Content-Type'));
- $delegate->process(Argument::any())->shouldHaveBeenCalledTimes(0);
+ $delegate->handle(Argument::any())->shouldHaveBeenCalledTimes(0);
}
}
diff --git a/module/Core/test/Response/NotFoundDelegateTest.php b/module/Core/test/Response/NotFoundDelegateTest.php
index 4f80bf562..b3ce2e66d 100644
--- a/module/Core/test/Response/NotFoundDelegateTest.php
+++ b/module/Core/test/Response/NotFoundDelegateTest.php
@@ -43,7 +43,7 @@ public function properResponseTypeIsReturned(string $expectedResponse, string $a
/** @var MethodProphecy $render */
$render = $this->renderer->render(Argument::cetera())->willReturn('');
- $resp = $this->delegate->process($request);
+ $resp = $this->delegate->handle($request);
$this->assertInstanceOf($expectedResponse, $resp);
$render->shouldHaveBeenCalledTimes($renderCalls);
diff --git a/module/Rest/src/Action/AbstractRestAction.php b/module/Rest/src/Action/AbstractRestAction.php
index 9ba1e6507..a9f491b6f 100644
--- a/module/Rest/src/Action/AbstractRestAction.php
+++ b/module/Rest/src/Action/AbstractRestAction.php
@@ -5,11 +5,11 @@
use Fig\Http\Message\RequestMethodInterface;
use Fig\Http\Message\StatusCodeInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
-abstract class AbstractRestAction implements MiddlewareInterface, RequestMethodInterface, StatusCodeInterface
+abstract class AbstractRestAction implements RequestHandlerInterface, RequestMethodInterface, StatusCodeInterface
{
/**
* @var LoggerInterface
diff --git a/module/Rest/src/Action/AuthenticateAction.php b/module/Rest/src/Action/AuthenticateAction.php
index f4ac08b0f..22dcee430 100644
--- a/module/Rest/src/Action/AuthenticateAction.php
+++ b/module/Rest/src/Action/AuthenticateAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -43,11 +42,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
$authData = $request->getParsedBody();
if (! isset($authData['apiKey'])) {
@@ -61,7 +59,7 @@ public function process(Request $request, DelegateInterface $delegate)
// Authenticate using provided API key
$apiKey = $this->apiKeyService->getByKey($authData['apiKey']);
- if (! isset($apiKey) || ! $apiKey->isValid()) {
+ if ($apiKey === null || ! $apiKey->isValid()) {
return new JsonResponse([
'error' => RestUtils::INVALID_API_KEY_ERROR,
'message' => $this->translator->translate('Provided API key does not exist or is invalid.'),
diff --git a/module/Rest/src/Action/CreateShortcodeAction.php b/module/Rest/src/Action/CreateShortcodeAction.php
index 561695924..b3c093d38 100644
--- a/module/Rest/src/Action/CreateShortcodeAction.php
+++ b/module/Rest/src/Action/CreateShortcodeAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -44,11 +43,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
$postData = (array) $request->getParsedBody();
if (! isset($postData['longUrl'])) {
diff --git a/module/Rest/src/Action/EditShortCodeAction.php b/module/Rest/src/Action/EditShortCodeAction.php
index a8f12de6a..3e9be062f 100644
--- a/module/Rest/src/Action/EditShortCodeAction.php
+++ b/module/Rest/src/Action/EditShortCodeAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
@@ -41,12 +40,11 @@ public function __construct(
* to the next middleware component to create the response.
*
* @param ServerRequestInterface $request
- * @param DelegateInterface $delegate
*
* @return ResponseInterface
* @throws \InvalidArgumentException
*/
- public function process(ServerRequestInterface $request, DelegateInterface $delegate): ResponseInterface
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
$postData = (array) $request->getParsedBody();
$shortCode = $request->getAttribute('shortCode', '');
diff --git a/module/Rest/src/Action/EditShortcodeTagsAction.php b/module/Rest/src/Action/EditShortcodeTagsAction.php
index b1aa6492b..c226605af 100644
--- a/module/Rest/src/Action/EditShortcodeTagsAction.php
+++ b/module/Rest/src/Action/EditShortcodeTagsAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -36,11 +35,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
$shortCode = $request->getAttribute('shortCode');
$bodyParams = $request->getParsedBody();
diff --git a/module/Rest/src/Action/GetVisitsAction.php b/module/Rest/src/Action/GetVisitsAction.php
index 490b04707..0892da85f 100644
--- a/module/Rest/src/Action/GetVisitsAction.php
+++ b/module/Rest/src/Action/GetVisitsAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -37,11 +36,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
$shortCode = $request->getAttribute('shortCode');
$startDate = $this->getDateQueryParam($request, 'startDate');
diff --git a/module/Rest/src/Action/ListShortcodesAction.php b/module/Rest/src/Action/ListShortcodesAction.php
index 83007e295..fe071a287 100644
--- a/module/Rest/src/Action/ListShortcodesAction.php
+++ b/module/Rest/src/Action/ListShortcodesAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -38,11 +37,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
try {
$params = $this->queryToListParams($request->getQueryParams());
@@ -61,13 +59,13 @@ public function process(Request $request, DelegateInterface $delegate)
* @param array $query
* @return array
*/
- public function queryToListParams(array $query)
+ private function queryToListParams(array $query): array
{
return [
- isset($query['page']) ? $query['page'] : 1,
- isset($query['searchTerm']) ? $query['searchTerm'] : null,
- isset($query['tags']) ? $query['tags'] : [],
- isset($query['orderBy']) ? $query['orderBy'] : null,
+ $query['page'] ?? 1,
+ $query['searchTerm'] ?? null,
+ $query['tags'] ?? [],
+ $query['orderBy'] ?? null,
];
}
}
diff --git a/module/Rest/src/Action/ResolveUrlAction.php b/module/Rest/src/Action/ResolveUrlAction.php
index 1abf56269..54109049f 100644
--- a/module/Rest/src/Action/ResolveUrlAction.php
+++ b/module/Rest/src/Action/ResolveUrlAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
@@ -37,11 +36,10 @@ public function __construct(
/**
* @param Request $request
- * @param DelegateInterface $delegate
- * @return null|Response
+ * @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function handle(Request $request): Response
{
$shortCode = $request->getAttribute('shortCode');
diff --git a/module/Rest/src/Action/Tag/CreateTagsAction.php b/module/Rest/src/Action/Tag/CreateTagsAction.php
index da27547c5..6f93b46fe 100644
--- a/module/Rest/src/Action/Tag/CreateTagsAction.php
+++ b/module/Rest/src/Action/Tag/CreateTagsAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
@@ -29,15 +28,14 @@ public function __construct(TagServiceInterface $tagService, LoggerInterface $lo
* to the next middleware component to create the response.
*
* @param ServerRequestInterface $request
- * @param DelegateInterface $delegate
*
* @return ResponseInterface
* @throws \InvalidArgumentException
*/
- public function process(ServerRequestInterface $request, DelegateInterface $delegate)
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
$body = $request->getParsedBody();
- $tags = isset($body['tags']) ? $body['tags'] : [];
+ $tags = $body['tags'] ?? [];
return new JsonResponse([
'tags' => [
diff --git a/module/Rest/src/Action/Tag/DeleteTagsAction.php b/module/Rest/src/Action/Tag/DeleteTagsAction.php
index ce172cb59..e7ae7b488 100644
--- a/module/Rest/src/Action/Tag/DeleteTagsAction.php
+++ b/module/Rest/src/Action/Tag/DeleteTagsAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
@@ -29,14 +28,13 @@ public function __construct(TagServiceInterface $tagService, LoggerInterface $lo
* to the next middleware component to create the response.
*
* @param ServerRequestInterface $request
- * @param DelegateInterface $delegate
*
* @return ResponseInterface
*/
- public function process(ServerRequestInterface $request, DelegateInterface $delegate)
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
$query = $request->getQueryParams();
- $tags = isset($query['tags']) ? $query['tags'] : [];
+ $tags = $query['tags'] ?? [];
$this->tagService->deleteTags($tags);
return new EmptyResponse();
diff --git a/module/Rest/src/Action/Tag/ListTagsAction.php b/module/Rest/src/Action/Tag/ListTagsAction.php
index c78f4ca45..79c6a79e0 100644
--- a/module/Rest/src/Action/Tag/ListTagsAction.php
+++ b/module/Rest/src/Action/Tag/ListTagsAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
@@ -29,12 +28,11 @@ public function __construct(TagServiceInterface $tagService, LoggerInterface $lo
* to the next middleware component to create the response.
*
* @param ServerRequestInterface $request
- * @param DelegateInterface $delegate
*
* @return ResponseInterface
* @throws \InvalidArgumentException
*/
- public function process(ServerRequestInterface $request, DelegateInterface $delegate)
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
return new JsonResponse([
'tags' => [
diff --git a/module/Rest/src/Action/Tag/UpdateTagAction.php b/module/Rest/src/Action/Tag/UpdateTagAction.php
index bb8fbbe21..d2e9b8713 100644
--- a/module/Rest/src/Action/Tag/UpdateTagAction.php
+++ b/module/Rest/src/Action/Tag/UpdateTagAction.php
@@ -3,7 +3,6 @@
namespace Shlinkio\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;
@@ -41,12 +40,11 @@ public function __construct(
* to the next middleware component to create the response.
*
* @param ServerRequestInterface $request
- * @param DelegateInterface $delegate
*
* @return ResponseInterface
* @throws \InvalidArgumentException
*/
- public function process(ServerRequestInterface $request, DelegateInterface $delegate)
+ public function handle(ServerRequestInterface $request): ResponseInterface
{
$body = $request->getParsedBody();
if (! isset($body['oldName'], $body['newName'])) {
diff --git a/module/Rest/src/Authentication/JWTService.php b/module/Rest/src/Authentication/JWTService.php
index 6a0d3ac87..0b4a99492 100644
--- a/module/Rest/src/Authentication/JWTService.php
+++ b/module/Rest/src/Authentication/JWTService.php
@@ -92,7 +92,7 @@ public function getPayload(string $jwt): array
* @param array $data
* @return string
*/
- protected function encode(array $data): string
+ private function encode(array $data): string
{
return JWT::encode($data, $this->appOptions->getSecretKey(), self::DEFAULT_ENCRYPTION_ALG);
}
@@ -101,7 +101,7 @@ protected function encode(array $data): string
* @param string $jwt
* @return array
*/
- protected function decode(string $jwt): array
+ private function decode(string $jwt): array
{
return (array) JWT::decode($jwt, $this->appOptions->getSecretKey(), [self::DEFAULT_ENCRYPTION_ALG]);
}
diff --git a/module/Rest/src/Entity/ApiKey.php b/module/Rest/src/Entity/ApiKey.php
index 284cc3028..fe475c3aa 100644
--- a/module/Rest/src/Entity/ApiKey.php
+++ b/module/Rest/src/Entity/ApiKey.php
@@ -44,7 +44,7 @@ public function __construct()
/**
* @return string
*/
- public function getKey()
+ public function getKey(): string
{
return $this->key;
}
@@ -53,7 +53,7 @@ public function getKey()
* @param string $key
* @return $this
*/
- public function setKey($key)
+ public function setKey($key): self
{
$this->key = $key;
return $this;
@@ -62,7 +62,7 @@ public function setKey($key)
/**
* @return \DateTime|null
*/
- public function getExpirationDate()
+ public function getExpirationDate(): ?\DateTime
{
return $this->expirationDate;
}
@@ -71,7 +71,7 @@ public function getExpirationDate()
* @param \DateTime $expirationDate
* @return $this
*/
- public function setExpirationDate($expirationDate)
+ public function setExpirationDate($expirationDate): self
{
$this->expirationDate = $expirationDate;
return $this;
@@ -80,9 +80,9 @@ public function setExpirationDate($expirationDate)
/**
* @return bool
*/
- public function isExpired()
+ public function isExpired(): bool
{
- if (! isset($this->expirationDate)) {
+ if ($this->expirationDate === null) {
return false;
}
@@ -92,7 +92,7 @@ public function isExpired()
/**
* @return boolean
*/
- public function isEnabled()
+ public function isEnabled(): bool
{
return $this->enabled;
}
@@ -101,7 +101,7 @@ public function isEnabled()
* @param boolean $enabled
* @return $this
*/
- public function setEnabled($enabled)
+ public function setEnabled($enabled): self
{
$this->enabled = $enabled;
return $this;
@@ -112,7 +112,7 @@ public function setEnabled($enabled)
*
* @return $this
*/
- public function disable()
+ public function disable(): self
{
return $this->setEnabled(false);
}
@@ -122,17 +122,17 @@ public function disable()
*
* @return bool
*/
- public function isValid()
+ public function isValid(): bool
{
return $this->isEnabled() && ! $this->isExpired();
}
/**
- * The string repesentation of an API key is the key itself
+ * The string representation of an API key is the key itself
*
* @return string
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getKey();
}
diff --git a/module/Rest/src/ErrorHandler/JsonErrorResponseGenerator.php b/module/Rest/src/ErrorHandler/JsonErrorResponseGenerator.php
index 7d0b6013a..035099c8a 100644
--- a/module/Rest/src/ErrorHandler/JsonErrorResponseGenerator.php
+++ b/module/Rest/src/ErrorHandler/JsonErrorResponseGenerator.php
@@ -20,7 +20,7 @@ class JsonErrorResponseGenerator implements ErrorResponseGeneratorInterface, Sta
* @return Response
* @throws \InvalidArgumentException
*/
- public function __invoke($e, Request $request, Response $response)
+ public function __invoke(?\Throwable $e, Request $request, Response $response)
{
$status = $response->getStatusCode();
$responsePhrase = $status < 400 ? 'Internal Server Error' : $response->getReasonPhrase();
@@ -32,8 +32,8 @@ public function __invoke($e, Request $request, Response $response)
], $status);
}
- protected function responsePhraseToCode(string $responsePhrase): string
+ private function responsePhraseToCode(string $responsePhrase): string
{
- return strtoupper(str_replace(' ', '_', $responsePhrase));
+ return \strtoupper(\str_replace(' ', '_', $responsePhrase));
}
}
diff --git a/module/Rest/src/Middleware/BodyParserMiddleware.php b/module/Rest/src/Middleware/BodyParserMiddleware.php
index 69929af45..1bbc26ea7 100644
--- a/module/Rest/src/Middleware/BodyParserMiddleware.php
+++ b/module/Rest/src/Middleware/BodyParserMiddleware.php
@@ -4,10 +4,10 @@
namespace Shlinkio\Shlink\Rest\Middleware;
use Fig\Http\Message\RequestMethodInterface;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Rest\Exception\RuntimeException;
class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterface
@@ -17,11 +17,11 @@ class BodyParserMiddleware implements MiddlewareInterface, RequestMethodInterfac
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
$method = $request->getMethod();
$currentParams = $request->getParsedBody();
@@ -32,16 +32,16 @@ public function process(Request $request, DelegateInterface $delegate)
self::METHOD_HEAD,
self::METHOD_OPTIONS,
], true)) {
- return $delegate->process($request);
+ return $handler->handle($request);
}
// If the accepted content is JSON, try to parse the body from JSON
$contentType = $this->getRequestContentType($request);
if (\in_array($contentType, ['application/json', 'text/json', 'application/x-json'], true)) {
- return $delegate->process($this->parseFromJson($request));
+ return $handler->handle($this->parseFromJson($request));
}
- return $delegate->process($this->parseFromUrlEncoded($request));
+ return $handler->handle($this->parseFromUrlEncoded($request));
}
/**
diff --git a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php
index 071eadba1..32e10ed87 100644
--- a/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php
+++ b/module/Rest/src/Middleware/CheckAuthenticationMiddleware.php
@@ -4,10 +4,10 @@
namespace Shlinkio\Shlink\Rest\Middleware;
use Fig\Http\Message\StatusCodeInterface;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Shlinkio\Shlink\Rest\Action\AuthenticateAction;
@@ -21,7 +21,7 @@
class CheckAuthenticationMiddleware implements MiddlewareInterface, StatusCodeInterface
{
- const AUTHORIZATION_HEADER = 'Authorization';
+ public const AUTHORIZATION_HEADER = 'Authorization';
/**
* @var TranslatorInterface
@@ -51,13 +51,13 @@ public function __construct(
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
* @throws \InvalidArgumentException
* @throws \ErrorException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
// If current route is the authenticate route or an OPTIONS request, continue to the next middleware
/** @var RouteResult|null $routeResult */
@@ -67,7 +67,7 @@ public function process(Request $request, DelegateInterface $delegate)
|| $routeResult->getMatchedRouteName() === AuthenticateAction::class
|| $request->getMethod() === 'OPTIONS'
) {
- return $delegate->process($request);
+ return $handler->handle($request);
}
// Check that the auth header was provided, and that it belongs to a non-expired token
@@ -77,22 +77,22 @@ public function process(Request $request, DelegateInterface $delegate)
// Get token making sure the an authorization type is provided
$authToken = $request->getHeaderLine(self::AUTHORIZATION_HEADER);
- $authTokenParts = explode(' ', $authToken);
- if (count($authTokenParts) === 1) {
+ $authTokenParts = \explode(' ', $authToken);
+ if (\count($authTokenParts) === 1) {
return new JsonResponse([
'error' => RestUtils::INVALID_AUTHORIZATION_ERROR,
- 'message' => sprintf($this->translator->translate(
+ 'message' => \sprintf($this->translator->translate(
'You need to provide the Bearer type in the %s header.'
), self::AUTHORIZATION_HEADER),
], self::STATUS_UNAUTHORIZED);
}
// Make sure the authorization type is Bearer
- list($authType, $jwt) = $authTokenParts;
- if (strtolower($authType) !== 'bearer') {
+ [$authType, $jwt] = $authTokenParts;
+ if (\strtolower($authType) !== 'bearer') {
return new JsonResponse([
'error' => RestUtils::INVALID_AUTHORIZATION_ERROR,
- 'message' => sprintf($this->translator->translate(
+ 'message' => \sprintf($this->translator->translate(
'Provided authorization type %s is not supported. Use Bearer instead.'
), $authType),
], self::STATUS_UNAUTHORIZED);
@@ -107,7 +107,7 @@ public function process(Request $request, DelegateInterface $delegate)
// Update the token expiration and continue to next middleware
$jwt = $this->jwtService->refresh($jwt);
- $response = $delegate->process($request);
+ $response = $handler->handle($request);
// Return the response with the updated token on it
return $response->withHeader(self::AUTHORIZATION_HEADER, 'Bearer ' . $jwt);
@@ -119,11 +119,15 @@ public function process(Request $request, DelegateInterface $delegate)
}
}
- protected function createTokenErrorResponse()
+ /**
+ * @return JsonResponse
+ * @throws \InvalidArgumentException
+ */
+ private function createTokenErrorResponse(): JsonResponse
{
return new JsonResponse([
'error' => RestUtils::INVALID_AUTH_TOKEN_ERROR,
- 'message' => sprintf(
+ 'message' => \sprintf(
$this->translator->translate(
'Missing or invalid auth token provided. Perform a new authentication request and send provided '
. 'token on every new request on the "%s" header'
diff --git a/module/Rest/src/Middleware/CrossDomainMiddleware.php b/module/Rest/src/Middleware/CrossDomainMiddleware.php
index 9237c743d..dc4bf9d69 100644
--- a/module/Rest/src/Middleware/CrossDomainMiddleware.php
+++ b/module/Rest/src/Middleware/CrossDomainMiddleware.php
@@ -4,10 +4,10 @@
namespace Shlinkio\Shlink\Rest\Middleware;
use Fig\Http\Message\RequestMethodInterface;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
class CrossDomainMiddleware implements MiddlewareInterface, RequestMethodInterface
{
@@ -16,15 +16,15 @@ class CrossDomainMiddleware implements MiddlewareInterface, RequestMethodInterfa
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
* @throws \InvalidArgumentException
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
/** @var Response $response */
- $response = $delegate->process($request);
+ $response = $handler->handle($request);
if (! $request->hasHeader('Origin')) {
return $response;
}
diff --git a/module/Rest/src/Middleware/PathVersionMiddleware.php b/module/Rest/src/Middleware/PathVersionMiddleware.php
index 18cfc3949..f8fc01137 100644
--- a/module/Rest/src/Middleware/PathVersionMiddleware.php
+++ b/module/Rest/src/Middleware/PathVersionMiddleware.php
@@ -3,10 +3,10 @@
namespace Shlinkio\Shlink\Rest\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
-use Interop\Http\ServerMiddleware\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
class PathVersionMiddleware implements MiddlewareInterface
{
@@ -15,18 +15,18 @@ class PathVersionMiddleware implements MiddlewareInterface
* to the next middleware component to create the response.
*
* @param Request $request
- * @param DelegateInterface $delegate
+ * @param RequestHandlerInterface $handler
*
* @return Response
*/
- public function process(Request $request, DelegateInterface $delegate)
+ public function process(Request $request, RequestHandlerInterface $handler): Response
{
$uri = $request->getUri();
$path = $uri->getPath();
// TODO Workaround... Do not process the request if it does not start with rest
if (\strpos($path, '/rest') !== 0) {
- return $delegate->process($request);
+ return $handler->handle($request);
}
// If the path does not begin with the version number, prepend v1 by default for BC compatibility purposes
@@ -41,6 +41,6 @@ public function process(Request $request, DelegateInterface $delegate)
$request = $request->withUri($uri->withPath(\implode('/', $parts)));
}
- return $delegate->process($request);
+ return $handler->handle($request);
}
}
diff --git a/module/Rest/src/Util/RestUtils.php b/module/Rest/src/Util/RestUtils.php
index b9d968910..1d6976761 100644
--- a/module/Rest/src/Util/RestUtils.php
+++ b/module/Rest/src/Util/RestUtils.php
@@ -9,16 +9,16 @@
class RestUtils
{
- const INVALID_SHORTCODE_ERROR = 'INVALID_SHORTCODE';
- const INVALID_URL_ERROR = 'INVALID_URL';
- const INVALID_ARGUMENT_ERROR = 'INVALID_ARGUMENT';
- const INVALID_SLUG_ERROR = 'INVALID_SLUG';
- const INVALID_CREDENTIALS_ERROR = 'INVALID_CREDENTIALS';
- const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN';
- const INVALID_AUTHORIZATION_ERROR = 'INVALID_AUTHORIZATION';
- const INVALID_API_KEY_ERROR = 'INVALID_API_KEY';
- const NOT_FOUND_ERROR = 'NOT_FOUND';
- const UNKNOWN_ERROR = 'UNKNOWN_ERROR';
+ public const INVALID_SHORTCODE_ERROR = 'INVALID_SHORTCODE';
+ public const INVALID_URL_ERROR = 'INVALID_URL';
+ public const INVALID_ARGUMENT_ERROR = 'INVALID_ARGUMENT';
+ public const INVALID_SLUG_ERROR = 'INVALID_SLUG';
+ public const INVALID_CREDENTIALS_ERROR = 'INVALID_CREDENTIALS';
+ public const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN';
+ public const INVALID_AUTHORIZATION_ERROR = 'INVALID_AUTHORIZATION';
+ public const INVALID_API_KEY_ERROR = 'INVALID_API_KEY';
+ public const NOT_FOUND_ERROR = 'NOT_FOUND';
+ public const UNKNOWN_ERROR = 'UNKNOWN_ERROR';
public static function getRestErrorCodeFromException(\Throwable $e)
{
diff --git a/module/Rest/test/Action/AuthenticateActionTest.php b/module/Rest/test/Action/AuthenticateActionTest.php
index 4fb2518f0..4825a1006 100644
--- a/module/Rest/test/Action/AuthenticateActionTest.php
+++ b/module/Rest/test/Action/AuthenticateActionTest.php
@@ -10,7 +10,6 @@
use Shlinkio\Shlink\Rest\Authentication\JWTService;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\Rest\Service\ApiKeyService;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\I18n\Translator\Translator;
@@ -47,7 +46,7 @@ public function setUp()
*/
public function notProvidingAuthDataReturnsError()
{
- $resp = $this->action->process(ServerRequestFactory::fromGlobals(), TestUtils::createDelegateMock()->reveal());
+ $resp = $this->action->handle(ServerRequestFactory::fromGlobals());
$this->assertEquals(400, $resp->getStatusCode());
}
@@ -62,7 +61,7 @@ public function properApiKeyReturnsTokenInResponse()
$request = ServerRequestFactory::fromGlobals()->withParsedBody([
'apiKey' => 'foo',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$response->getBody()->rewind();
@@ -80,7 +79,7 @@ public function invalidApiKeyReturnsErrorResponse()
$request = ServerRequestFactory::fromGlobals()->withParsedBody([
'apiKey' => 'foo',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(401, $response->getStatusCode());
}
}
diff --git a/module/Rest/test/Action/CreateShortcodeActionTest.php b/module/Rest/test/Action/CreateShortcodeActionTest.php
index 2c92f0304..c9d8ff194 100644
--- a/module/Rest/test/Action/CreateShortcodeActionTest.php
+++ b/module/Rest/test/Action/CreateShortcodeActionTest.php
@@ -11,7 +11,6 @@
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Rest\Action\CreateShortcodeAction;
use Shlinkio\Shlink\Rest\Util\RestUtils;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Uri;
use Zend\I18n\Translator\Translator;
@@ -41,10 +40,7 @@ public function setUp()
*/
public function missingLongUrlParamReturnsError()
{
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals(),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals());
$this->assertEquals(400, $response->getStatusCode());
}
@@ -60,7 +56,7 @@ public function properShortcodeConversionReturnsData()
$request = ServerRequestFactory::fromGlobals()->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), 'http://foo.com/abc123') > 0);
}
@@ -77,7 +73,7 @@ public function anInvalidUrlReturnsError()
$request = ServerRequestFactory::fromGlobals()->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(400, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_URL_ERROR) > 0);
}
@@ -100,7 +96,7 @@ public function nonUniqueSlugReturnsError()
'longUrl' => 'http://www.domain.com/foo/bar',
'customSlug' => 'foo',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(400, $response->getStatusCode());
$this->assertContains(RestUtils::INVALID_SLUG_ERROR, (string) $response->getBody());
}
@@ -117,7 +113,7 @@ public function aGenericExceptionWillReturnError()
$request = ServerRequestFactory::fromGlobals()->withParsedBody([
'longUrl' => 'http://www.domain.com/foo/bar',
]);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(500, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::UNKNOWN_ERROR) > 0);
}
diff --git a/module/Rest/test/Action/EditShortCodeActionTest.php b/module/Rest/test/Action/EditShortCodeActionTest.php
index 2690811ab..5a4e6b2f0 100644
--- a/module/Rest/test/Action/EditShortCodeActionTest.php
+++ b/module/Rest/test/Action/EditShortCodeActionTest.php
@@ -3,7 +3,6 @@
namespace ShlinkioTest\Shlink\Rest\Action;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
@@ -43,7 +42,7 @@ public function invalidDataReturnsError()
]);
/** @var JsonResponse $resp */
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$payload = $resp->getPayload();
$this->assertEquals(400, $resp->getStatusCode());
@@ -65,7 +64,7 @@ public function incorrectShortCodeReturnsError()
);
/** @var JsonResponse $resp */
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$payload = $resp->getPayload();
$this->assertEquals(404, $resp->getStatusCode());
@@ -85,7 +84,7 @@ public function correctShortCodeReturnsSuccess()
]);
$updateMeta = $this->shortUrlService->updateMetadataByShortCode(Argument::cetera())->willReturn(new ShortUrl());
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$this->assertEquals(204, $resp->getStatusCode());
$updateMeta->shouldHaveBeenCalled();
diff --git a/module/Rest/test/Action/EditShortcodeTagsActionTest.php b/module/Rest/test/Action/EditShortcodeTagsActionTest.php
index f90c73f09..a2bcfb383 100644
--- a/module/Rest/test/Action/EditShortcodeTagsActionTest.php
+++ b/module/Rest/test/Action/EditShortcodeTagsActionTest.php
@@ -9,7 +9,6 @@
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Rest\Action\EditShortcodeTagsAction;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\I18n\Translator\Translator;
@@ -35,10 +34,7 @@ public function setUp()
*/
public function notProvidingTagsReturnsError()
{
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withAttribute('shortCode', 'abc123'),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withAttribute('shortCode', 'abc123'));
$this->assertEquals(400, $response->getStatusCode());
}
@@ -51,10 +47,9 @@ public function anInvalidShortCodeReturnsNotFound()
$this->shortUrlService->setTagsByShortCode($shortCode, [])->willThrow(InvalidShortCodeException::class)
->shouldBeCalledTimes(1);
- $response = $this->action->process(
+ $response = $this->action->handle(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', 'abc123')
- ->withParsedBody(['tags' => []]),
- TestUtils::createDelegateMock()->reveal()
+ ->withParsedBody(['tags' => []])
);
$this->assertEquals(404, $response->getStatusCode());
}
@@ -68,10 +63,9 @@ public function tagsListIsReturnedIfCorrectShortCodeIsProvided()
$this->shortUrlService->setTagsByShortCode($shortCode, [])->willReturn(new ShortUrl())
->shouldBeCalledTimes(1);
- $response = $this->action->process(
+ $response = $this->action->handle(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', 'abc123')
- ->withParsedBody(['tags' => []]),
- TestUtils::createDelegateMock()->reveal()
+ ->withParsedBody(['tags' => []])
);
$this->assertEquals(200, $response->getStatusCode());
}
diff --git a/module/Rest/test/Action/GetVisitsActionTest.php b/module/Rest/test/Action/GetVisitsActionTest.php
index eb892e74d..1ac988ba5 100644
--- a/module/Rest/test/Action/GetVisitsActionTest.php
+++ b/module/Rest/test/Action/GetVisitsActionTest.php
@@ -10,7 +10,6 @@
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
use Shlinkio\Shlink\Rest\Action\GetVisitsAction;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\I18n\Translator\Translator;
@@ -40,10 +39,7 @@ public function providingCorrectShortCodeReturnsVisits()
$this->visitsTracker->info($shortCode, Argument::type(DateRange::class))->willReturn([])
->shouldBeCalledTimes(1);
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode));
$this->assertEquals(200, $response->getStatusCode());
}
@@ -57,10 +53,7 @@ public function providingInvalidShortCodeReturnsError()
InvalidArgumentException::class
)->shouldBeCalledTimes(1);
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode));
$this->assertEquals(404, $response->getStatusCode());
}
@@ -74,10 +67,7 @@ public function unexpectedExceptionWillReturnError()
\Exception::class
)->shouldBeCalledTimes(1);
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode));
$this->assertEquals(500, $response->getStatusCode());
}
@@ -91,10 +81,9 @@ public function datesAreReadFromQuery()
->willReturn([])
->shouldBeCalledTimes(1);
- $response = $this->action->process(
+ $response = $this->action->handle(
ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode)
- ->withQueryParams(['endDate' => '2016-01-01 00:00:00']),
- TestUtils::createDelegateMock()->reveal()
+ ->withQueryParams(['endDate' => '2016-01-01 00:00:00'])
);
$this->assertEquals(200, $response->getStatusCode());
}
diff --git a/module/Rest/test/Action/ListShortcodesActionTest.php b/module/Rest/test/Action/ListShortCodesActionTest.php
similarity index 75%
rename from module/Rest/test/Action/ListShortcodesActionTest.php
rename to module/Rest/test/Action/ListShortCodesActionTest.php
index 1867d15a3..85e6737aa 100644
--- a/module/Rest/test/Action/ListShortcodesActionTest.php
+++ b/module/Rest/test/Action/ListShortCodesActionTest.php
@@ -7,7 +7,6 @@
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Rest\Action\ListShortcodesAction;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\I18n\Translator\Translator;
use Zend\Paginator\Adapter\ArrayAdapter;
@@ -39,12 +38,9 @@ public function properListReturnsSuccessResponse()
$this->service->listShortUrls($page, null, [], null)->willReturn(new Paginator(new ArrayAdapter()))
->shouldBeCalledTimes(1);
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withQueryParams([
- 'page' => $page,
- ]),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withQueryParams([
+ 'page' => $page,
+ ]));
$this->assertEquals(200, $response->getStatusCode());
}
@@ -57,12 +53,9 @@ public function anExceptionsReturnsErrorResponse()
$this->service->listShortUrls($page, null, [], null)->willThrow(\Exception::class)
->shouldBeCalledTimes(1);
- $response = $this->action->process(
- ServerRequestFactory::fromGlobals()->withQueryParams([
- 'page' => $page,
- ]),
- TestUtils::createDelegateMock()->reveal()
- );
+ $response = $this->action->handle(ServerRequestFactory::fromGlobals()->withQueryParams([
+ 'page' => $page,
+ ]));
$this->assertEquals(500, $response->getStatusCode());
}
}
diff --git a/module/Rest/test/Action/ResolveUrlActionTest.php b/module/Rest/test/Action/ResolveUrlActionTest.php
index 884fae55d..feafc4254 100644
--- a/module/Rest/test/Action/ResolveUrlActionTest.php
+++ b/module/Rest/test/Action/ResolveUrlActionTest.php
@@ -10,7 +10,6 @@
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Rest\Action\ResolveUrlAction;
use Shlinkio\Shlink\Rest\Util\RestUtils;
-use ShlinkioTest\Shlink\Common\Util\TestUtils;
use Zend\Diactoros\ServerRequestFactory;
use Zend\I18n\Translator\Translator;
@@ -41,7 +40,7 @@ public function incorrectShortCodeReturnsError()
->shouldBeCalledTimes(1);
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(404, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_ARGUMENT_ERROR) > 0);
}
@@ -56,7 +55,7 @@ public function correctShortCodeReturnsSuccess()
->shouldBeCalledTimes(1);
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), 'http://domain.com/foo/bar') > 0);
}
@@ -71,7 +70,7 @@ public function invalidShortCodeExceptionReturnsError()
->shouldBeCalledTimes(1);
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(400, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_SHORTCODE_ERROR) > 0);
}
@@ -86,7 +85,7 @@ public function unexpectedExceptionWillReturnError()
->shouldBeCalledTimes(1);
$request = ServerRequestFactory::fromGlobals()->withAttribute('shortCode', $shortCode);
- $response = $this->action->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(500, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::UNKNOWN_ERROR) > 0);
}
diff --git a/module/Rest/test/Action/Tag/CreateTagsActionTest.php b/module/Rest/test/Action/Tag/CreateTagsActionTest.php
index 795827fa5..e94a0ea87 100644
--- a/module/Rest/test/Action/Tag/CreateTagsActionTest.php
+++ b/module/Rest/test/Action/Tag/CreateTagsActionTest.php
@@ -4,7 +4,6 @@
namespace ShlinkioTest\Shlink\Rest\Action\Tag;
use Doctrine\Common\Collections\ArrayCollection;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
@@ -40,7 +39,7 @@ public function processDelegatesIntoService($tags)
/** @var MethodProphecy $deleteTags */
$deleteTags = $this->tagService->createTags($tags ?: [])->willReturn(new ArrayCollection());
- $response = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(200, $response->getStatusCode());
$deleteTags->shouldHaveBeenCalled();
diff --git a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php
index 0a0657bf2..fc376576d 100644
--- a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php
+++ b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php
@@ -3,7 +3,6 @@
namespace ShlinkioTest\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
@@ -39,7 +38,7 @@ public function processDelegatesIntoService($tags)
/** @var MethodProphecy $deleteTags */
$deleteTags = $this->tagService->deleteTags($tags ?: []);
- $response = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $response = $this->action->handle($request);
$this->assertEquals(204, $response->getStatusCode());
$deleteTags->shouldHaveBeenCalled();
diff --git a/module/Rest/test/Action/Tag/ListTagsActionTest.php b/module/Rest/test/Action/Tag/ListTagsActionTest.php
index 67e395b11..7fb73404e 100644
--- a/module/Rest/test/Action/Tag/ListTagsActionTest.php
+++ b/module/Rest/test/Action/Tag/ListTagsActionTest.php
@@ -3,7 +3,6 @@
namespace ShlinkioTest\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
@@ -37,10 +36,7 @@ public function returnsDataFromService()
/** @var MethodProphecy $listTags */
$listTags = $this->tagService->listTags()->willReturn([new Tag('foo'), new Tag('bar')]);
- $resp = $this->action->process(
- ServerRequestFactory::fromGlobals(),
- $this->prophesize(DelegateInterface::class)->reveal()
- );
+ $resp = $this->action->handle(ServerRequestFactory::fromGlobals());
$this->assertEquals([
'tags' => [
diff --git a/module/Rest/test/Action/Tag/UpdateTagActionTest.php b/module/Rest/test/Action/Tag/UpdateTagActionTest.php
index fbbd7c609..c073f2706 100644
--- a/module/Rest/test/Action/Tag/UpdateTagActionTest.php
+++ b/module/Rest/test/Action/Tag/UpdateTagActionTest.php
@@ -3,7 +3,6 @@
namespace ShlinkioTest\Shlink\Rest\Action\Tag;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
@@ -39,7 +38,7 @@ public function setUp()
public function whenInvalidParamsAreProvidedAnErrorIsReturned(array $bodyParams)
{
$request = ServerRequestFactory::fromGlobals()->withParsedBody($bodyParams);
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$this->assertEquals(400, $resp->getStatusCode());
}
@@ -65,7 +64,7 @@ public function requestingInvalidTagReturnsError()
/** @var MethodProphecy $rename */
$rename = $this->tagService->renameTag('foo', 'bar')->willThrow(EntityDoesNotExistException::class);
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$this->assertEquals(404, $resp->getStatusCode());
$rename->shouldHaveBeenCalled();
@@ -83,7 +82,7 @@ public function correctInvocationRenamesTag()
/** @var MethodProphecy $rename */
$rename = $this->tagService->renameTag('foo', 'bar')->willReturn(new Tag());
- $resp = $this->action->process($request, $this->prophesize(DelegateInterface::class)->reveal());
+ $resp = $this->action->handle($request);
$this->assertEquals(204, $resp->getStatusCode());
$rename->shouldHaveBeenCalled();
diff --git a/module/Rest/test/Middleware/BodyParserMiddlewareTest.php b/module/Rest/test/Middleware/BodyParserMiddlewareTest.php
index 1c927f4f3..e433322ba 100644
--- a/module/Rest/test/Middleware/BodyParserMiddlewareTest.php
+++ b/module/Rest/test/Middleware/BodyParserMiddlewareTest.php
@@ -3,11 +3,11 @@
namespace ShlinkioTest\Shlink\Rest\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\MethodProphecy;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Rest\Middleware\BodyParserMiddleware;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
@@ -31,9 +31,9 @@ public function setUp()
public function requestsFromOtherMethodsJustFallbackToNextMiddleware()
{
$request = ServerRequestFactory::fromGlobals()->withMethod('GET');
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
@@ -51,9 +51,9 @@ public function jsonRequestsAreJsonDecoded()
$request = ServerRequestFactory::fromGlobals()->withMethod('PUT')
->withBody($body)
->withHeader('content-type', 'application/json');
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process(Argument::type(ServerRequestInterface::class))->will(
+ $process = $delegate->handle(Argument::type(ServerRequestInterface::class))->will(
function (array $args) use ($test) {
/** @var ServerRequestInterface $req */
$req = array_shift($args);
@@ -82,9 +82,9 @@ public function regularRequestsAreUrlDecoded()
$body->write('foo=bar&bar[]=one&bar[]=5');
$request = ServerRequestFactory::fromGlobals()->withMethod('PUT')
->withBody($body);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process(Argument::type(ServerRequestInterface::class))->will(
+ $process = $delegate->handle(Argument::type(ServerRequestInterface::class))->will(
function (array $args) use ($test) {
/** @var ServerRequestInterface $req */
$req = array_shift($args);
diff --git a/module/Rest/test/Middleware/CheckAuthenticationMiddlewareTest.php b/module/Rest/test/Middleware/CheckAuthenticationMiddlewareTest.php
index 9c805d1b4..fa7f7d063 100644
--- a/module/Rest/test/Middleware/CheckAuthenticationMiddlewareTest.php
+++ b/module/Rest/test/Middleware/CheckAuthenticationMiddlewareTest.php
@@ -3,10 +3,10 @@
namespace ShlinkioTest\Shlink\Rest\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\MethodProphecy;
use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Rest\Action\AuthenticateAction;
use Shlinkio\Shlink\Rest\Authentication\JWTService;
use Shlinkio\Shlink\Rest\Middleware\CheckAuthenticationMiddleware;
@@ -16,7 +16,6 @@
use Zend\Expressive\Router\Route;
use Zend\Expressive\Router\RouteResult;
use Zend\I18n\Translator\Translator;
-
use function Zend\Stratigility\middleware;
class CheckAuthenticationMiddlewareTest extends TestCase
@@ -50,9 +49,9 @@ public function setUp()
public function someWhiteListedSituationsFallbackToNextMiddleware()
{
$request = ServerRequestFactory::fromGlobals();
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
$process->shouldHaveBeenCalledTimes(1);
@@ -61,9 +60,9 @@ public function someWhiteListedSituationsFallbackToNextMiddleware()
RouteResult::class,
RouteResult::fromRouteFailure(['GET'])
);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
$process->shouldHaveBeenCalledTimes(1);
@@ -76,9 +75,9 @@ public function someWhiteListedSituationsFallbackToNextMiddleware()
AuthenticateAction::class
))
);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
$process->shouldHaveBeenCalledTimes(1);
@@ -86,9 +85,9 @@ public function someWhiteListedSituationsFallbackToNextMiddleware()
RouteResult::class,
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
)->withMethod('OPTIONS');
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
$process->shouldHaveBeenCalledTimes(1);
}
@@ -102,7 +101,7 @@ public function noHeaderReturnsError()
RouteResult::class,
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
);
- $response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->middleware->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals(401, $response->getStatusCode());
}
@@ -117,7 +116,7 @@ public function provideAnAuthorizationWithoutTypeReturnsError()
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, $authToken);
- $response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->middleware->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals(401, $response->getStatusCode());
$this->assertTrue(strpos($response->getBody()->getContents(), 'You need to provide the Bearer type') > 0);
@@ -134,7 +133,7 @@ public function provideAnAuthorizationWithWrongTypeReturnsError()
RouteResult::fromRoute(new Route('bar', $this->dummyMiddleware), [])
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, 'Basic ' . $authToken);
- $response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->middleware->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals(401, $response->getStatusCode());
$this->assertTrue(
@@ -154,7 +153,7 @@ public function provideAnExpiredTokenReturnsError()
)->withHeader(CheckAuthenticationMiddleware::AUTHORIZATION_HEADER, 'Bearer ' . $authToken);
$this->jwtService->verify($authToken)->willReturn(false)->shouldBeCalledTimes(1);
- $response = $this->middleware->process($request, TestUtils::createDelegateMock()->reveal());
+ $response = $this->middleware->process($request, TestUtils::createReqHandlerMock()->reveal());
$this->assertEquals(401, $response->getStatusCode());
}
@@ -171,9 +170,9 @@ public function provideCorrectTokenUpdatesExpirationAndFallsBackToNextMiddleware
$this->jwtService->verify($authToken)->willReturn(true)->shouldBeCalledTimes(1);
$this->jwtService->refresh($authToken)->willReturn($authToken)->shouldBeCalledTimes(1);
- $delegate = $this->prophesize(DelegateInterface::class);
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
/** @var MethodProphecy $process */
- $process = $delegate->process($request)->willReturn(new Response());
+ $process = $delegate->handle($request)->willReturn(new Response());
$resp = $this->middleware->process($request, $delegate->reveal());
$process->shouldHaveBeenCalledTimes(1);
diff --git a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
index dcc7e878b..478113ff4 100644
--- a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
+++ b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
@@ -3,10 +3,10 @@
namespace ShlinkioTest\Shlink\Rest\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Rest\Middleware\CrossDomainMiddleware;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
@@ -25,7 +25,7 @@ class CrossDomainMiddlewareTest extends TestCase
public function setUp()
{
$this->middleware = new CrossDomainMiddleware();
- $this->delegate = $this->prophesize(DelegateInterface::class);
+ $this->delegate = $this->prophesize(RequestHandlerInterface::class);
}
/**
@@ -34,7 +34,7 @@ public function setUp()
public function nonCrossDomainRequestsAreNotAffected()
{
$originalResponse = new Response();
- $this->delegate->process(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
+ $this->delegate->handle(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
$response = $this->middleware->process(ServerRequestFactory::fromGlobals(), $this->delegate->reveal());
$this->assertSame($originalResponse, $response);
@@ -50,7 +50,7 @@ public function nonCrossDomainRequestsAreNotAffected()
public function anyRequestIncludesTheAllowAccessHeader()
{
$originalResponse = new Response();
- $this->delegate->process(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
+ $this->delegate->handle(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
$response = $this->middleware->process(
ServerRequestFactory::fromGlobals()->withHeader('Origin', 'local'),
@@ -70,7 +70,7 @@ public function optionsRequestIncludesMoreHeaders()
{
$originalResponse = new Response();
$request = ServerRequestFactory::fromGlobals()->withMethod('OPTIONS')->withHeader('Origin', 'local');
- $this->delegate->process(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
+ $this->delegate->handle(Argument::any())->willReturn($originalResponse)->shouldbeCalledTimes(1);
$response = $this->middleware->process($request, $this->delegate->reveal());
$this->assertNotSame($originalResponse, $response);
diff --git a/module/Rest/test/Middleware/PathVersionMiddlewareTest.php b/module/Rest/test/Middleware/PathVersionMiddlewareTest.php
index 4c98d4f22..e024c1285 100644
--- a/module/Rest/test/Middleware/PathVersionMiddlewareTest.php
+++ b/module/Rest/test/Middleware/PathVersionMiddlewareTest.php
@@ -3,11 +3,11 @@
namespace ShlinkioTest\Shlink\Rest\Middleware;
-use Interop\Http\ServerMiddleware\DelegateInterface;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Psr\Http\Message\ServerRequestInterface as Request;
+use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Rest\Middleware\PathVersionMiddleware;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
@@ -32,8 +32,8 @@ public function whenVersionIsProvidedRequestRemainsUnchanged()
{
$request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/rest/v2/foo'));
- $delegate = $this->prophesize(DelegateInterface::class);
- $process = $delegate->process($request)->willReturn(new Response());
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
@@ -47,8 +47,8 @@ public function whenPathDoesNotStartWithRestRemainsUnchanged()
{
$request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/foo'));
- $delegate = $this->prophesize(DelegateInterface::class);
- $process = $delegate->process($request)->willReturn(new Response());
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $process = $delegate->handle($request)->willReturn(new Response());
$this->middleware->process($request, $delegate->reveal());
@@ -62,8 +62,8 @@ public function versionOneIsPrependedWhenNoVersionIsDefined()
{
$request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/rest/bar/baz'));
- $delegate = $this->prophesize(DelegateInterface::class);
- $delegate->process(Argument::type(Request::class))->will(function (array $args) use ($request) {
+ $delegate = $this->prophesize(RequestHandlerInterface::class);
+ $delegate->handle(Argument::type(Request::class))->will(function (array $args) use ($request) {
$req = \array_shift($args);
Assert::assertNotSame($request, $req);
diff --git a/phpstan.neon b/phpstan.neon
index 77e32e1e8..00a81049a 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,3 +1,4 @@
parameters:
excludes_analyse:
- module/Common/src/Template/Extension/TranslatorExtension.php
+ - module/Rest/src/Util/RestUtils.php
diff --git a/public/index.php b/public/index.php
index 3f2c0f849..fa5d778c1 100644
--- a/public/index.php
+++ b/public/index.php
@@ -1,9 +1,9 @@
get(Application::class)->run();
+$container->get(Application::class)->run();