diff --git a/.circleci/config.yml b/.circleci/config.yml
index dac96a0..1818ac6 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -22,6 +22,7 @@ jobs:
- ./vendor
key: v1-dependencies-{{ checksum "composer.json" }}
+ - run: composer lint
- run: composer phpcs
- run: composer phpstan
- run: composer test
diff --git a/.gitignore b/.gitignore
index 987e2a2..e96516b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
composer.lock
vendor
+.phpunit.result.cache
diff --git a/composer.json b/composer.json
index 153252a..e3a4124 100644
--- a/composer.json
+++ b/composer.json
@@ -13,24 +13,29 @@
},
"require": {
"php": ">=7.2",
- "nette/neon": "^2.4",
- "slim/slim": "^3.9",
- "nette/utils": "^2.5",
- "nette/di": "^2.4",
+ "nette/neon": "^3.0",
+ "slim/slim": "^3.12",
+ "nette/utils": "^3.0",
+ "nette/di": "^3.0",
"psr/http-message": "^1.0"
},
"require-dev": {
- "phpunit/phpunit": "^7",
+ "phpunit/phpunit": "^8",
"roave/security-advisories": "dev-master",
- "phpstan/phpstan": "^0.10",
- "mockery/mockery": "dev-master",
- "slevomat/coding-standard": "^4.8",
- "phpstan/phpstan-phpunit": "^0.10.0"
+ "mockery/mockery": "^1.2",
+ "brandembassy/coding-standard": "^5.3"
},
"scripts": {
- "test": "vendor/bin/phpunit tests",
- "phpcs": "vendor/bin/phpcs --standard=ruleset.xml src tests --ignore=tests/temp",
- "phpcbf": "./vendor/bin/phpcbf --standard=ruleset.xml src tests --ignore=tests/temp",
- "phpstan": "vendor/bin/phpstan analyse src tests -l max -c phpstan.neon"
+ "lint": " find src tests -name \"*.php\" -print0 | xargs -0 -n1 -P8 php -l",
+ "phpcs": "./vendor/bin/phpcs --ignore=\"tests/temp/*\" --standard=ruleset.xml src tests",
+ "phpcbf": "./vendor/bin/phpcbf --standard=ruleset.xml src tests",
+ "phpstan": "./vendor/bin/phpstan analyse src tests",
+ "test": "./vendor/bin/phpunit tests"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "config": {
+ "sort-packages": true,
+ "process-timeout": 600
}
}
diff --git a/phpstan.neon b/phpstan.neon
index 9128f66..69ecde1 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -2,8 +2,6 @@ parameters:
excludes_analyse:
- %rootDir%/../../../tests/temp/*
- ignoreErrors:
- - '#Call to an undefined method Mockery\\ExpectationInterface|Mockery\\HigherOrderMessage::andReturn().#'
-
includes:
- - vendor/phpstan/phpstan-phpunit/extension.neon
+ - vendor/brandembassy/coding-standard/default-phpstan.neon
+
diff --git a/ruleset.xml b/ruleset.xml
index dc2da08..1d4dc3b 100644
--- a/ruleset.xml
+++ b/ruleset.xml
@@ -1,78 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ActionHandler.php b/src/ActionHandler.php
index 7041562..c1e6d50 100644
--- a/src/ActionHandler.php
+++ b/src/ActionHandler.php
@@ -7,11 +7,10 @@
interface ActionHandler
{
-
/**
- * @param RequestInterface $request
+ * @param RequestInterface $request
* @param ResponseInterface $response
- * @param array $arguments
+ * @param mixed[] $arguments
* @return ResponseInterface
*/
public function __invoke(
@@ -19,5 +18,4 @@ public function __invoke(
ResponseInterface $response,
array $arguments = []
): ResponseInterface;
-
}
diff --git a/src/Controller.php b/src/Controller.php
index de5b219..9d11345 100644
--- a/src/Controller.php
+++ b/src/Controller.php
@@ -12,17 +12,18 @@
*/
abstract class Controller extends Container
{
-
public function beforeAction(RequestInterface $request, ResponseInterface $response): void
{
// intentionally - this method is empty in default
}
+
public function afterAction(RequestInterface $request, ResponseInterface $response): void
{
// intentionally - this method is empty in default
}
+
public function middleware(RequestInterface $request, ResponseInterface $response, Route $next): ResponseInterface
{
$this->beforeAction($request, $response);
@@ -32,5 +33,4 @@ public function middleware(RequestInterface $request, ResponseInterface $respons
return $response;
}
-
}
diff --git a/src/DI/SlimApiExtension.php b/src/DI/SlimApiExtension.php
index 396f610..1c40f75 100644
--- a/src/DI/SlimApiExtension.php
+++ b/src/DI/SlimApiExtension.php
@@ -7,15 +7,15 @@
final class SlimApiExtension extends CompilerExtension
{
-
/**
- * @var array
+ * @var mixed[]
*/
private $defaults = [
- 'apiDefinitionKey' => 'api',
+ 'apiDefinitionKey' => 'api',
'slimConfiguration' => [],
];
+
public function loadConfiguration(): void
{
$this->validateConfig($this->defaults);
@@ -23,5 +23,4 @@ public function loadConfiguration(): void
$builder->addDefinition($this->prefix('slimApi.factory'))
->setFactory(SlimApplicationFactory::class, [$this->config]);
}
-
}
diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php
index cdc7662..98d8e83 100644
--- a/src/ErrorHandler.php
+++ b/src/ErrorHandler.php
@@ -8,11 +8,9 @@
interface ErrorHandler
{
-
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
?Throwable $e = null
): ResponseInterface;
-
}
diff --git a/src/Middleware.php b/src/Middleware.php
index 0c3039d..dbb371b 100644
--- a/src/Middleware.php
+++ b/src/Middleware.php
@@ -7,7 +7,5 @@
interface Middleware
{
-
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface;
-
}
diff --git a/src/MissingApiArgumentException.php b/src/MissingApiArgumentException.php
index b00795e..0bde0bb 100644
--- a/src/MissingApiArgumentException.php
+++ b/src/MissingApiArgumentException.php
@@ -6,5 +6,4 @@
final class MissingApiArgumentException extends Exception implements RequestException
{
-
}
diff --git a/src/Request/Request.php b/src/Request/Request.php
index 72350ef..580ea66 100644
--- a/src/Request/Request.php
+++ b/src/Request/Request.php
@@ -13,10 +13,11 @@
use Psr\Http\Message\UriInterface;
use Slim\Route;
use stdClass;
+use function array_key_exists;
+use function sprintf;
final class Request implements RequestInterface
{
-
/**
* @var stdClass|null
*/
@@ -27,13 +28,17 @@ final class Request implements RequestInterface
*/
private $request;
+
public function __construct(ServerRequestInterface $request)
{
$this->request = $request;
}
+
/**
- * @inheritdoc
+ * @param string $key
+ * @param string|int|null $default
+ * @return string|integer|null
*/
public function getQueryParam(string $key, $default = null)
{
@@ -47,10 +52,7 @@ public function getQueryParam(string $key, $default = null)
return $result;
}
- /**
- * @inheritdoc
- * @throws MissingApiArgumentException
- */
+
public function getRequiredArgument(string $name): string
{
$arguments = $this->request->getAttributes();
@@ -59,30 +61,33 @@ public function getRequiredArgument(string $name): string
$value = Strings::trim($value);
if ($value === '') {
- throw new MissingApiArgumentException(\sprintf('Missing "%s" argument', $name));
+ throw new MissingApiArgumentException(sprintf('Missing "%s" argument', $name));
}
return $value;
}
+
/**
- * @inheritdoc
- * @throws MissingApiArgumentException
+ * @param string $name
+ * @return mixed[]|stdClass|string
*/
public function getField(string $name)
{
$body = $this->getDecodedJsonFromBody();
if (!$this->hasField($name)) {
- throw new MissingApiArgumentException(\sprintf('Field "%s" is missing in request body', $name));
+ throw new MissingApiArgumentException(sprintf('Field "%s" is missing in request body', $name));
}
- return $body->$name;
+ return ((array)$body)[$name];
}
+
/**
- * @inheritdoc
- * @throws MissingApiArgumentException
+ * @param string $name
+ * @param int|string|null $default
+ * @return mixed[]|stdClass|string|integer|null
*/
public function getOptionalField($name, $default = null)
{
@@ -91,217 +96,267 @@ public function getOptionalField($name, $default = null)
: $default;
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @return boolean
*/
public function hasField($name): bool
{
- return \array_key_exists($name, (array)$this->getDecodedJsonFromBody());
+ return array_key_exists($name, (array)$this->getDecodedJsonFromBody());
}
+
public function getProtocolVersion(): string
{
return $this->request->getProtocolVersion();
}
+
/**
- * @inheritDoc
+ * @param string $version
+ * @return static
*/
- public function withProtocolVersion($version)
+ public function withProtocolVersion($version): self
{
return new static($this->request->withProtocolVersion($version));
}
+
/**
- * @inheritDoc
+ * @return string[][]
*/
public function getHeaders(): array
{
return $this->request->getHeaders();
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @return boolean
*/
public function hasHeader($name): bool
{
return $this->request->hasHeader($name);
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @return string[]
*/
public function getHeader($name): array
{
return $this->request->getHeader($name);
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @return string
*/
public function getHeaderLine($name): string
{
return $this->request->getHeaderLine($name);
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @param string|string[] $value
+ * @return static
*/
- public function withHeader($name, $value)
+ public function withHeader($name, $value): self
{
return new static($this->request->withHeader($name, $value));
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @param string|string[] $value
+ * @return static
*/
- public function withAddedHeader($name, $value)
+ public function withAddedHeader($name, $value): self
{
return new static($this->request->withAddedHeader($name, $value));
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @return static
*/
- public function withoutHeader($name)
+ public function withoutHeader($name): self
{
return new static($this->request->withoutHeader($name));
}
+
public function getBody(): StreamInterface
{
return $this->request->getBody();
}
+
/**
- * @inheritDoc
+ * @param StreamInterface $body
+ * @return static
*/
- public function withBody(StreamInterface $body)
+ public function withBody(StreamInterface $body): self
{
return new static($this->request->withBody($body));
}
+
public function getRequestTarget(): string
{
return $this->request->getRequestTarget();
}
+
/**
- * @inheritDoc
+ * @param mixed $requestTarget
+ * @return static
*/
- public function withRequestTarget($requestTarget)
+ public function withRequestTarget($requestTarget): self
{
return new static($this->request->withRequestTarget($requestTarget));
}
+
public function getMethod(): string
{
return $this->request->getMethod();
}
+
/**
- * @inheritDoc
+ * @param string $method
+ * @return static
*/
- public function withMethod($method)
+ public function withMethod($method): self
{
return new static($this->request->withMethod($method));
}
+
public function getUri(): UriInterface
{
return $this->request->getUri();
}
+
/**
- * @inheritDoc
+ * @param UriInterface $uri
+ * @param bool $preserveHost
+ * @return static
*/
- public function withUri(UriInterface $uri, $preserveHost = false)
+ public function withUri(UriInterface $uri, $preserveHost = false): self
{
return new static($this->request->withUri($uri, $preserveHost));
}
+
/**
- * @inheritDoc
+ * @return mixed[]
*/
public function getServerParams(): array
{
return $this->request->getServerParams();
}
+
/**
- * @inheritDoc
+ * @return mixed[]
*/
public function getCookieParams(): array
{
return $this->request->getCookieParams();
}
+
/**
- * @inheritDoc
+ * @param mixed[] $cookies
+ * @return static
*/
- public function withCookieParams(array $cookies)
+ public function withCookieParams(array $cookies): self
{
return new static($this->request->withCookieParams($cookies));
}
+
/**
- * @inheritDoc
+ * @return mixed[]
*/
public function getQueryParams(): array
{
return $this->request->getQueryParams();
}
+
/**
- * @inheritDoc
+ * @param mixed[] $query
+ * @return static
*/
- public function withQueryParams(array $query)
+ public function withQueryParams(array $query): self
{
return new static($this->request->withQueryParams($query));
}
+
/**
- * @inheritDoc
+ * @return mixed[]
*/
public function getUploadedFiles(): array
{
return $this->request->getUploadedFiles();
}
+
/**
- * @inheritDoc
+ * @param mixed[] $uploadedFiles
+ * @return static
*/
public function withUploadedFiles(array $uploadedFiles)
{
return new static($this->request->withUploadedFiles($uploadedFiles));
}
+
/**
- * @inheritDoc
+ * @return mixed[]|object|null
*/
public function getParsedBody()
{
return $this->request->getParsedBody();
}
+
/**
- * @inheritDoc
+ * @param mixed[]|object|null $data
+ * @return static
*/
- public function withParsedBody($data)
+ public function withParsedBody($data): self
{
return new static($this->request->withParsedBody($data));
}
+
/**
- * @inheritDoc
+ * @return mixed[]
*/
public function getAttributes(): array
{
return $this->request->getAttributes();
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @param mixed $default
+ * @return mixed
*/
public function getAttribute($name, $default = null)
{
@@ -318,24 +373,30 @@ public function getAttribute($name, $default = null)
return $value;
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @param mixed $value
+ * @return static
*/
- public function withAttribute($name, $value)
+ public function withAttribute($name, $value): self
{
return new static($this->request->withAttribute($name, $value));
}
+
/**
- * @inheritDoc
+ * @param string $name
+ * @return static
*/
- public function withoutAttribute($name)
+ public function withoutAttribute($name): self
{
return new static($this->request->withoutAttribute($name));
}
+
/**
- * @inheritdoc
+ * @return mixed[]|object
*/
public function getDecodedJsonFromBody()
{
@@ -347,21 +408,21 @@ public function getDecodedJsonFromBody()
return $this->decodedJsonFromBody;
}
+
public function getDateTimeQueryParam(string $field): DateTimeImmutable
{
- $datetimeParam = $this->getQueryParam($field);
+ $datetimeParam = (string)$this->getQueryParam($field);
- if ($datetimeParam === null) {
- throw new LogicException(\sprintf('Could not find %s in request\'s params', $field));
+ if ($datetimeParam === '') {
+ throw new LogicException(sprintf('Could not find %s in request\'s params', $field));
}
$datetime = DateTimeImmutable::createFromFormat(DateTime::ATOM, $datetimeParam);
if ($datetime === false || $datetime->format(DateTime::ATOM) !== $datetimeParam) {
- throw new LogicException(\sprintf('Could not parse %s as datetime', $field));
+ throw new LogicException(sprintf('Could not parse %s as datetime', $field));
}
return $datetime;
}
-
}
diff --git a/src/Request/RequestInterface.php b/src/Request/RequestInterface.php
index e64293e..0336aa6 100644
--- a/src/Request/RequestInterface.php
+++ b/src/Request/RequestInterface.php
@@ -8,36 +8,40 @@
interface RequestInterface extends ServerRequestInterface
{
-
/**
- * @param string $key
- * @param mixed $default
- * @return mixed|null
+ * @param string $key
+ * @param string|int|null $default
+ * @return string|integer|null
*/
public function getQueryParam(string $key, $default = null);
+
public function getRequiredArgument(string $name): string;
+
/**
* @param string $name
- * @return array|stdClass|string
+ * @return mixed[]|stdClass|string
*/
public function getField(string $name);
+
/**
- * @param string $name
- * @param mixed $default
- * @return mixed
+ * @param string $name
+ * @param string|int|null $default
+ * @return mixed[]|stdClass|string|integer|null
*/
public function getOptionalField(string $name, $default = null);
+
public function hasField(string $name): bool;
+
/**
- * @return mixed
+ * @return mixed[]|object
*/
public function getDecodedJsonFromBody();
- public function getDateTimeQueryParam(string $key): DateTimeImmutable;
+ public function getDateTimeQueryParam(string $key): DateTimeImmutable;
}
diff --git a/src/RequestException.php b/src/RequestException.php
index e79d4ab..b472fd5 100644
--- a/src/RequestException.php
+++ b/src/RequestException.php
@@ -4,5 +4,4 @@
interface RequestException
{
-
}
diff --git a/src/Response/Response.php b/src/Response/Response.php
index 55beebb..9f26fa8 100644
--- a/src/Response/Response.php
+++ b/src/Response/Response.php
@@ -7,123 +7,152 @@
final class Response implements ResponseInterface
{
-
/**
* @var SlimResponse
*/
private $slimResponse;
+
public function __construct(SlimResponse $slimResponse)
{
$this->slimResponse = $slimResponse;
}
+
public function getProtocolVersion(): string
{
return $this->slimResponse->getProtocolVersion();
}
+
/**
- * @inheritdoc
+ * @param string $version
+ * @return static
*/
- public function withProtocolVersion($version)
+ public function withProtocolVersion($version): self
{
return new static($this->slimResponse->withProtocolVersion($version));
}
+
/**
- * @inheritdoc
+ * @return string[][]
*/
public function getHeaders(): array
{
return $this->slimResponse->getHeaders();
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @return boolean
*/
public function hasHeader($name): bool
{
return $this->slimResponse->hasHeader($name);
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @return string[]
*/
public function getHeader($name): array
{
return $this->slimResponse->getHeader($name);
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @return string
*/
public function getHeaderLine($name): string
{
return $this->slimResponse->getHeaderLine($name);
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @param string|string[] $value
+ * @return static
*/
- public function withHeader($name, $value)
+ public function withHeader($name, $value): self
{
return new static($this->slimResponse->withHeader($name, $value));
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @param string|string[] $value
+ * @return static
*/
- public function withAddedHeader($name, $value)
+ public function withAddedHeader($name, $value): self
{
return new static($this->slimResponse->withAddedHeader($name, $value));
}
+
/**
- * @inheritdoc
+ * @param string $name
+ * @return static
*/
- public function withoutHeader($name)
+ public function withoutHeader($name): self
{
return new static($this->slimResponse->withoutHeader($name));
}
+
public function getBody(): StreamInterface
{
return $this->slimResponse->getBody();
}
+
/**
- * @inheritdoc
+ * @param StreamInterface $body
+ * @return static
*/
- public function withBody(StreamInterface $body)
+ public function withBody(StreamInterface $body): self
{
return new static($this->slimResponse->withBody($body));
}
+
public function getStatusCode(): int
{
return $this->slimResponse->getStatusCode();
}
+
/**
- * @inheritdoc
+ * @param int $code
+ * @param string $reasonPhrase
+ * @return static
*/
- public function withStatus($code, $reasonPhrase = '')
+ public function withStatus($code, $reasonPhrase = ''): self
{
return new static($this->slimResponse->withStatus($code, $reasonPhrase));
}
+
/**
- * @inheritdoc
+ * @param mixed[]|object $data
+ * @param int|null $status
+ * @param int $encodingOptions
+ * @return static
*/
- public function withJson($data, $status = null, $encodingOptions = 0)
+ public function withJson($data, ?int $status = null, int $encodingOptions = 0): self
{
return new static($this->slimResponse->withJson($data, $status, $encodingOptions));
}
+
public function getReasonPhrase(): string
{
return $this->slimResponse->getReasonPhrase();
}
-
}
diff --git a/src/Response/ResponseInterface.php b/src/Response/ResponseInterface.php
index 1c84583..9be14fc 100644
--- a/src/Response/ResponseInterface.php
+++ b/src/Response/ResponseInterface.php
@@ -6,13 +6,11 @@
interface ResponseInterface extends PsrResponseInterface
{
-
/**
- * @param mixed $data
- * @param int|null $status
- * @param int $encodingOptions
+ * @param mixed[]|object $data
+ * @param int|null $status
+ * @param int $encodingOptions
* @return static
*/
- public function withJson($data, $status = null, $encodingOptions = 0);
-
+ public function withJson($data, ?int $status = null, int $encodingOptions = 0);
}
diff --git a/src/SlimApp.php b/src/SlimApp.php
index 5f24fe6..a20bf5b 100644
--- a/src/SlimApp.php
+++ b/src/SlimApp.php
@@ -6,13 +6,10 @@
use BrandEmbassy\Slim\Response\Response;
use Psr\Http\Message\ResponseInterface;
use Slim\App;
+use function reset;
class SlimApp extends App
{
-
- /**
- * @inheritdoc
- */
public function run($silent = false): ResponseInterface
{
$request = new Request($this->getContainer()->get('request'));
@@ -20,7 +17,7 @@ public function run($silent = false): ResponseInterface
$response = $this->process($request, $response);
$contentTypes = $response->getHeader('Content-Type');
- $contentType = \reset($contentTypes);
+ $contentType = reset($contentTypes);
if ($contentType === 'text/html; charset=UTF-8' && $response->getBody()->getSize() === 0) {
$response = $response->withHeader('Content-Type', 'text/plain; charset=UTF-8');
@@ -32,5 +29,4 @@ public function run($silent = false): ResponseInterface
return $response;
}
-
}
diff --git a/src/SlimApplicationFactory.php b/src/SlimApplicationFactory.php
index 7b214cd..c5530c1 100644
--- a/src/SlimApplicationFactory.php
+++ b/src/SlimApplicationFactory.php
@@ -8,12 +8,16 @@
use LogicException;
use Nette\DI\Container;
use Slim\Collection;
+use Throwable;
+use function gettype;
+use function is_array;
+use function sprintf;
+use function trim;
final class SlimApplicationFactory
{
-
/**
- * @var array
+ * @var mixed[]
*/
private $configuration;
@@ -23,12 +27,13 @@ final class SlimApplicationFactory
private $container;
/**
- * @var Middleware[]
+ * @var array
*/
private $beforeRoutesMiddlewares;
+
/**
- * @param array $configuration
+ * @param mixed[] $configuration
* @param Container $container
*/
public function __construct(array $configuration, Container $container)
@@ -38,6 +43,7 @@ public function __construct(array $configuration, Container $container)
$this->beforeRoutesMiddlewares = [];
}
+
public function create(): SlimApp
{
$app = new SlimApp($this->configuration['slimConfiguration']);
@@ -72,16 +78,17 @@ public function create(): SlimApp
return $app;
}
+
/**
* @param string $configurationCode
- * @return array
+ * @return mixed[]
*/
private function getConfiguration(string $configurationCode): array
{
$configuration = $this->container->getParameters()[$configurationCode];
- if (!\is_array($configuration)) {
- throw new LogicException(\sprintf('Missing %s configuration', $configurationCode));
+ if (!is_array($configuration)) {
+ throw new LogicException(sprintf('Missing %s configuration', $configurationCode));
}
$this->validateConfiguration($configuration, $configurationCode, 'routes', 'array');
@@ -93,11 +100,12 @@ private function getConfiguration(string $configurationCode): array
return $configuration;
}
+
/**
- * @param array $configuration
- * @param string $configurationCode
- * @param string $name
- * @param string $type
+ * @param mixed[] $configuration
+ * @param string $configurationCode
+ * @param string $name
+ * @param string $type
*/
private function validateConfiguration(
array $configuration,
@@ -105,19 +113,20 @@ private function validateConfiguration(
string $name,
string $type
): void {
- if (!isset($configuration[$name]) || \gettype($configuration[$name]) !== $type) {
+ if (!isset($configuration[$name]) || gettype($configuration[$name]) !== $type) {
throw new LogicException(
- \sprintf(
+ sprintf(
'Missing or empty %s.%s configuration (has to be %s, but is %s)',
$configurationCode,
$name,
$type,
- \gettype($configuration[$name] ?? null)
+ gettype($configuration[$name] ?? null)
)
);
}
}
+
/**
* @param string $serviceName
* @return Closure
@@ -136,18 +145,20 @@ private function getServiceProvider(string $serviceName): callable
};
}
+
private function removeDefaultSlimErrorHandlers(SlimApp $app): void
{
$app->getContainer()['phpErrorHandler'] = static function () {
- return static function (RequestInterface $request, ResponseInterface $response, \Throwable $e): void {
+ return static function (RequestInterface $request, ResponseInterface $response, Throwable $e): void {
throw $e;
};
};
}
+
/**
* @param SlimApp $app
- * @param array $handlers
+ * @param mixed[] $handlers
*/
private function registerHandlers(SlimApp $app, array $handlers): void
{
@@ -156,6 +167,7 @@ private function registerHandlers(SlimApp $app, array $handlers): void
}
}
+
private function registerServiceIntoContainer(SlimApp $app, string $serviceName): void
{
if (!$app->getContainer()->has($serviceName)) {
@@ -163,10 +175,11 @@ private function registerServiceIntoContainer(SlimApp $app, string $serviceName)
}
}
+
/**
* @param SlimApp $app
- * @param array $api
- * @param string $apiName
+ * @param mixed[] $api
+ * @param string $apiName
*/
private function registerApis(SlimApp $app, array $api, string $apiName): void
{
@@ -175,11 +188,12 @@ private function registerApis(SlimApp $app, array $api, string $apiName): void
}
}
+
/**
* @param SlimApp $app
- * @param string $apiName
- * @param string $version
- * @param array $routes
+ * @param string $apiName
+ * @param string $version
+ * @param mixed[] $routes
*/
private function registerApi(SlimApp $app, string $apiName, string $version, array $routes): void
{
@@ -194,11 +208,12 @@ private function registerApi(SlimApp $app, string $apiName, string $version, arr
}
}
+
/**
* @deprecated Do not use Controllers, use Invokable Action classes (use MiddleWareInterface)
* @param SlimApp $app
- * @param string $urlPattern
- * @param array $routeData
+ * @param string $urlPattern
+ * @param mixed[] $routeData
*/
private function registerControllerRoute(SlimApp $app, string $urlPattern, array $routeData): void
{
@@ -206,14 +221,15 @@ private function registerControllerRoute(SlimApp $app, string $urlPattern, array
foreach ($routeData['methods'] as $method => $action) {
$app->map([$method], $urlPattern, $routeData['service'] . ':' . $action)
- ->add($routeData['service'] . ':' . 'middleware');
+ ->add($routeData['service'] . ':middleware');
}
}
+
/**
* @param SlimApp $app
- * @param array $routeData
- * @param string $urlPattern
+ * @param mixed[] $routeData
+ * @param string $urlPattern
*/
private function registerInvokableActionRoutes(SlimApp $app, array $routeData, string $urlPattern): void
{
@@ -237,11 +253,12 @@ private function registerInvokableActionRoutes(SlimApp $app, array $routeData, s
}
}
+
private function createUrlPattern(string $apiName, string $version, string $routeName): string
{
- $apiName = \trim($apiName, '/');
- $version = \trim($version, '/');
- $routeName = \trim($routeName, '/');
+ $apiName = trim($apiName, '/');
+ $version = trim($version, '/');
+ $routeName = trim($routeName, '/');
if ($version !== '') {
$version = '/' . $version;
@@ -258,15 +275,17 @@ private function createUrlPattern(string $apiName, string $version, string $rout
return $apiName . $version . $routeName;
}
+
private function registerBeforeRequestMiddleware(SlimApp $app, string $middleware): void
{
$this->registerServiceIntoContainer($app, $middleware);
$app->add($middleware);
}
+
/**
* @param SlimApp $app
- * @param array $configuration
+ * @param mixed[] $configuration
*/
private function registerBeforeRouteMiddlewares(SlimApp $app, array $configuration): void
{
@@ -277,5 +296,4 @@ private function registerBeforeRouteMiddlewares(SlimApp $app, array $configurati
}
}
}
-
}
diff --git a/tests/Dummy/ApiErrorHandler.php b/tests/Dummy/ApiErrorHandler.php
index 80520c8..402d02a 100644
--- a/tests/Dummy/ApiErrorHandler.php
+++ b/tests/Dummy/ApiErrorHandler.php
@@ -9,7 +9,6 @@
final class ApiErrorHandler implements ErrorHandler
{
-
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
@@ -21,5 +20,4 @@ public function __invoke(
return $response->withJson(['error' => $error], 500);
}
-
}
diff --git a/tests/Dummy/BeforeRequestMiddleware.php b/tests/Dummy/BeforeRequestMiddleware.php
index 26233c8..7522249 100644
--- a/tests/Dummy/BeforeRequestMiddleware.php
+++ b/tests/Dummy/BeforeRequestMiddleware.php
@@ -8,7 +8,6 @@
class BeforeRequestMiddleware implements Middleware
{
-
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
{
$response = $response->withAddedHeader(
@@ -18,5 +17,4 @@ public function __invoke(RequestInterface $request, ResponseInterface $response,
return $next($request, $response);
}
-
}
diff --git a/tests/Dummy/BeforeRouteMiddleware.php b/tests/Dummy/BeforeRouteMiddleware.php
index 7499223..dde11be 100644
--- a/tests/Dummy/BeforeRouteMiddleware.php
+++ b/tests/Dummy/BeforeRouteMiddleware.php
@@ -8,7 +8,6 @@
class BeforeRouteMiddleware implements Middleware
{
-
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
{
$response = $response->withAddedHeader(
@@ -18,5 +17,4 @@ public function __invoke(RequestInterface $request, ResponseInterface $response,
return $next($request, $response);
}
-
}
diff --git a/tests/Dummy/CreateChannelAction.php b/tests/Dummy/CreateChannelAction.php
index e936b67..86eae2d 100644
--- a/tests/Dummy/CreateChannelAction.php
+++ b/tests/Dummy/CreateChannelAction.php
@@ -8,7 +8,6 @@
final class CreateChannelAction implements ActionHandler
{
-
/**
* @inheritdoc
*/
@@ -19,5 +18,4 @@ public function __invoke(
): ResponseInterface {
return $response->withJson(['channelId' => 'fb_1234'], 201);
}
-
}
diff --git a/tests/Dummy/ErroringAction.php b/tests/Dummy/ErroringAction.php
index f560fce..43b53de 100644
--- a/tests/Dummy/ErroringAction.php
+++ b/tests/Dummy/ErroringAction.php
@@ -9,7 +9,13 @@
final class ErroringAction implements ActionHandler
{
-
+ // phpcs:disable
+ /**
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @param mixed[] $arguments
+ * @return ResponseInterface
+ */
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
@@ -17,5 +23,5 @@ public function __invoke(
): ResponseInterface {
throw new LogicException('Error or not to error, that\'s the question!');
}
-
+ // phpcs:enable
}
diff --git a/tests/Dummy/GetHelloWorldAction.php b/tests/Dummy/GetHelloWorldAction.php
index 51bec9e..0cd92f3 100644
--- a/tests/Dummy/GetHelloWorldAction.php
+++ b/tests/Dummy/GetHelloWorldAction.php
@@ -8,13 +8,17 @@
final class GetHelloWorldAction implements ActionHandler
{
-
+ /**
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @param mixed[] $arguments
+ * @return ResponseInterface
+ */
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
array $arguments = []
): ResponseInterface {
- return $response->withJson('Hello World');
+ return $response->withJson(['Hello World']);
}
-
}
diff --git a/tests/Dummy/GoldenKeyAuthMiddleware.php b/tests/Dummy/GoldenKeyAuthMiddleware.php
index e4ccf30..c3f5073 100644
--- a/tests/Dummy/GoldenKeyAuthMiddleware.php
+++ b/tests/Dummy/GoldenKeyAuthMiddleware.php
@@ -5,19 +5,14 @@
use BrandEmbassy\Slim\Middleware;
use BrandEmbassy\Slim\Request\RequestInterface;
use BrandEmbassy\Slim\Response\ResponseInterface;
-use Exception;
+use function reset;
final class GoldenKeyAuthMiddleware implements Middleware
{
-
- /**
- * @inheritdoc
- * @throws Exception
- */
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
{
$headerData = $request->getHeader('goldenKey');
- $token = \reset($headerData);
+ $token = reset($headerData);
$token = $token !== false
? $token
: '';
@@ -28,5 +23,4 @@ public function __invoke(RequestInterface $request, ResponseInterface $response,
return $next($request, $response);
}
-
}
diff --git a/tests/Dummy/NotAllowedHandler.php b/tests/Dummy/NotAllowedHandler.php
index e3a848b..73fb851 100644
--- a/tests/Dummy/NotAllowedHandler.php
+++ b/tests/Dummy/NotAllowedHandler.php
@@ -10,10 +10,8 @@
*/
final class NotAllowedHandler
{
-
public function __invoke(RequestInterface $request, ResponseInterface $response): ResponseInterface
{
return $response->withJson(['error' => 'Dummy NotAllowedHandler here!'], 405);
}
-
}
diff --git a/tests/Dummy/NotFoundHandler.php b/tests/Dummy/NotFoundHandler.php
index 8208e16..07c341f 100644
--- a/tests/Dummy/NotFoundHandler.php
+++ b/tests/Dummy/NotFoundHandler.php
@@ -9,7 +9,6 @@
final class NotFoundHandler implements ErrorHandler
{
-
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
@@ -17,5 +16,4 @@ public function __invoke(
): ResponseInterface {
return $response->withJson(['error' => 'Dummy NotFoundHandler here!'], 404);
}
-
}
diff --git a/tests/Request/RequestTest.php b/tests/Request/RequestTest.php
index 54d181d..8fb8a76 100644
--- a/tests/Request/RequestTest.php
+++ b/tests/Request/RequestTest.php
@@ -14,13 +14,17 @@
use Slim\Http\Headers;
use Slim\Http\Request as SlimRequest;
use Slim\Http\Uri;
+use function assert;
+use function fopen;
+use function is_resource;
+use function sprintf;
final class RequestTest extends TestCase
{
-
private const PARAM_NAME = 'dateFrom';
private const DATE_TIME_STRING = '2017-06-10T01:00:00+01:00';
+
public function testShouldDistinguishBetweenNullAndEmptyOption(): void
{
$request = $this->createDummyRequest();
@@ -30,6 +34,7 @@ public function testShouldDistinguishBetweenNullAndEmptyOption(): void
self::assertTrue($request->hasField('thisIsGandalf'));
}
+
public function testShouldRaiseExceptionForMissingRequiredField(): void
{
$request = $this->createDummyRequest();
@@ -39,6 +44,7 @@ public function testShouldRaiseExceptionForMissingRequiredField(): void
$request->getField('nonExistingField');
}
+
public function testGettingDateTimeQueryParam(): void
{
$arguments = [self::PARAM_NAME => self::DATE_TIME_STRING];
@@ -50,10 +56,11 @@ public function testGettingDateTimeQueryParam(): void
self::assertSame(self::DATE_TIME_STRING, $dateTime->format(DateTime::ATOM));
}
+
/**
* @dataProvider getDataForInvalidDateTimeArgument
- * @param string $logicExceptionMessage
- * @param array $arguments
+ * @param string $logicExceptionMessage
+ * @param mixed[] $arguments
*/
public function testGettingDateTimeQueryParamThrowsExceptionIfInvalidArgument(
string $logicExceptionMessage,
@@ -67,25 +74,27 @@ public function testGettingDateTimeQueryParamThrowsExceptionIfInvalidArgument(
$request->getDateTimeQueryParam(self::PARAM_NAME);
}
+
/**
- * @return array
+ * @return mixed[]
*/
public function getDataForInvalidDateTimeArgument(): array
{
return [
'Missing from' => [
- \sprintf('Could not find %s in request\'s params', self::PARAM_NAME),
+ sprintf('Could not find %s in request\'s params', self::PARAM_NAME),
[],
],
'Invalid from' => [
- \sprintf('Could not parse %s as datetime', self::PARAM_NAME),
+ sprintf('Could not parse %s as datetime', self::PARAM_NAME),
[self::PARAM_NAME => '123456789'],
],
];
}
+
/**
- * @param array $arguments
+ * @param mixed[] $arguments
* @return MockInterface&SlimRequest
*/
private function createMockSlimRequest(array $arguments): MockInterface
@@ -97,6 +106,7 @@ private function createMockSlimRequest(array $arguments): MockInterface
return $mock;
}
+
private function createRequest(StreamInterface $body): Request
{
$url = new Uri('https', 'example.com');
@@ -105,15 +115,15 @@ private function createRequest(StreamInterface $body): Request
return new Request($slimRequest);
}
+
private function createDummyRequest(): Request
{
- $resource = \fopen('php://temp', 'rb+');
- \assert(\is_resource($resource));
+ $resource = fopen('php://temp', 'rb+');
+ assert(is_resource($resource));
$body = new Body($resource);
$body->write('{"thisIsNull": null, "thisIsGandalf": "gandalf"}');
$body->rewind();
return $this->createRequest($body);
}
-
}
diff --git a/tests/SlimApplicationFactoryTest.php b/tests/SlimApplicationFactoryTest.php
index 639440f..c2d3628 100644
--- a/tests/SlimApplicationFactoryTest.php
+++ b/tests/SlimApplicationFactoryTest.php
@@ -16,24 +16,29 @@
use Slim\Http\Headers;
use Slim\Http\Request as SlimRequest;
use Slim\Http\Uri;
+use function assert;
+use function fopen;
+use function is_resource;
+use function md5;
final class SlimApplicationFactoryTest extends TestCase
{
-
public function testShouldPassSettingsToSlimContainer(): void
{
$app = $this->createSlimApp();
$settings = $app->getContainer()->get('settings');
- $this->assertSame('Dummy', $settings['myCustomOption']);
+ self::assertSame('Dummy', $settings['myCustomOption']);
}
+
public function testShouldAllowEmptyErrorHandlers(): void
{
$this->createSlimApp(__DIR__ . '/configNoHandlers.neon');
$this->expectNotToPerformAssertions();
}
+
public function testHandledRouteForOmittedUrlParts(): void
{
$request = $this->createRequest('GET', '/app');
@@ -42,9 +47,10 @@ public function testHandledRouteForOmittedUrlParts(): void
$response = $this->createSlimApp()->process($request, new Response(new \Slim\Http\Response()));
self::assertEquals(200, $response->getStatusCode());
- self::assertEquals('"Hello World"', $this->getContents($response));
+ self::assertEquals('["Hello World"]', $this->getContents($response));
}
+
public function testShouldBeHandledByNotFoundErrorHandler(): void
{
$request = $this->createRequest('POST', '/non-existing/path');
@@ -56,6 +62,7 @@ public function testShouldBeHandledByNotFoundErrorHandler(): void
self::assertEquals('{"error":"Dummy NotFoundHandler here!"}', $this->getContents($response));
}
+
public function testShouldBeHandledByNotAllowedHandler(): void
{
$request = $this->createRequest('PATCH', '/new-api/2.0/channels');
@@ -67,6 +74,7 @@ public function testShouldBeHandledByNotAllowedHandler(): void
self::assertEquals('{"error":"Dummy NotAllowedHandler here!"}', $this->getContents($response));
}
+
public function testShouldBeHandledByApiErrorHandler(): void
{
$request = $this->createRequest('POST', '/new-api/2.0/error');
@@ -78,6 +86,7 @@ public function testShouldBeHandledByApiErrorHandler(): void
self::assertEquals('{"error":"Error or not to error, that\'s the question!"}', $this->getContents($response));
}
+
public function testShouldDenyRequestByAccessMiddleware(): void
{
$request = $this->createRequest('POST', '/new-api/2.0/channels');
@@ -89,6 +98,7 @@ public function testShouldDenyRequestByAccessMiddleware(): void
self::assertEquals('{"error":"YOU SHALL NOT PASS!"}', $this->getContents($response));
}
+
public function testShouldAllowRequestByAccessMiddleware(): void
{
$request = $this->createRequest(
@@ -104,6 +114,7 @@ public function testShouldAllowRequestByAccessMiddleware(): void
self::assertEquals('{"channelId":"fb_1234"}', $this->getContents($response));
}
+
public function testShouldProcessBothGlobalMiddlewares(): void
{
$request = $this->createRequest('POST', '/new-api/2.0/channels');
@@ -122,6 +133,7 @@ public function testShouldProcessBothGlobalMiddlewares(): void
);
}
+
public function testShouldProcessBeforeRequestMiddleware(): void
{
$request = $this->createRequest('POST', '/non-existing/path');
@@ -135,6 +147,7 @@ public function testShouldProcessBeforeRequestMiddleware(): void
);
}
+
private function createContainer(string $configPath = __DIR__ . '/config.neon'): Container
{
$loader = new ContainerLoader(__DIR__ . '/temp', true);
@@ -143,22 +156,23 @@ static function (Compiler $compiler) use ($configPath): void {
$compiler->loadConfig($configPath);
$compiler->addExtension('extensions', new ExtensionsExtension());
},
- \md5($configPath)
+ md5($configPath)
);
return new $class();
}
+
/**
- * @param string $requestMethod
- * @param string $requestUrlPath
- * @param string[] $headers
+ * @param string $requestMethod
+ * @param string $requestUrlPath
+ * @param array $headers
* @return Request
*/
private function createRequest(string $requestMethod, string $requestUrlPath, array $headers = []): Request
{
- $body = \fopen('php://temp', 'rb+');
- \assert(\is_resource($body));
+ $body = fopen('php://temp', 'rb+');
+ assert(is_resource($body));
$slimRequest = new SlimRequest(
$requestMethod,
new Uri('http', 'api.be.com', 80, $requestUrlPath),
@@ -171,6 +185,7 @@ private function createRequest(string $requestMethod, string $requestUrlPath, ar
return new Request($slimRequest);
}
+
private function createSlimApp(string $configPath = __DIR__ . '/config.neon'): App
{
/** @var SlimApplicationFactory $factory */
@@ -179,6 +194,7 @@ private function createSlimApp(string $configPath = __DIR__ . '/config.neon'): A
return $factory->create();
}
+
private function getContents(ResponseInterface $response): string
{
$body = $response->getBody();
@@ -186,5 +202,4 @@ private function getContents(ResponseInterface $response): string
return $body->getContents();
}
-
}