Skip to content
Open

v3.2 #126

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<UnnecessaryVarAnnotation errorLevel="suppress" />
<UnresolvableInclude errorLevel="suppress" />
<UnusedClass errorLevel="suppress" />
<UnusedFunctionCall errorLevel="suppress" />
<UnusedParam errorLevel="suppress" />
<UnusedVariable errorLevel="suppress" />
</issueHandlers>
</psalm>
19 changes: 19 additions & 0 deletions resources/definitions/middlewares/base64_decoding_middleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

use Psr\Http\Message\StreamFactoryInterface;
use Sunrise\Http\Router\Middleware\Base64DecodingMiddleware;

use function DI\add;
use function DI\create;
use function DI\get;

return [
'router.route_middlewares' => add([
create(Base64DecodingMiddleware::class)
->constructor(
streamFactory: get(StreamFactoryInterface::class),
)
]),
];
50 changes: 50 additions & 0 deletions src/Middleware/Base64DecodingMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/**
* It's free open-source software released under the MIT License.
*
* @author Anatoly Nekhay <[email protected]>
* @copyright Copyright (c) 2018, Anatoly Nekhay
* @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
* @link https://github.com/sunrise-php/http-router
*/

declare(strict_types=1);

namespace Sunrise\Http\Router\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

/**
* @since 3.2.0
*/
final class Base64DecodingMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly StreamFactoryInterface $streamFactory,
) {
}

/**
* @inheritDoc
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Encoding
if ($request->getHeaderLine('Content-Encoding') === 'base64') {
/** @var resource $resource */
$resource = $request->getBody()->detach();
// https://www.php.net/manual/en/filters.convert.php
\stream_filter_append($resource, 'convert.base64-decode');

$body = $this->streamFactory->createStreamFromResource($resource);
$request = $request->withBody($body);
}

return $handler->handle($request);
}
}
28 changes: 28 additions & 0 deletions src/OpenApi/Annotation/SchemaName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* It's free open-source software released under the MIT License.
*
* @author Anatoly Nekhay <[email protected]>
* @copyright Copyright (c) 2018, Anatoly Nekhay
* @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
* @link https://github.com/sunrise-php/http-router
*/

declare(strict_types=1);

namespace Sunrise\Http\Router\OpenApi\Annotation;

use Attribute;

/**
* @since 3.2.0
*/
#[Attribute(Attribute::TARGET_CLASS)]
final class SchemaName
{
public function __construct(
public readonly string $value,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
$phpTypeName = $phpType->name;

$arrayPhpType = new Type(Type::PHP_TYPE_NAME_ARRAY, $phpType->allowsNull);
/** @var array{oneOf: array{0: array{type: 'array'}, 1: array{type: 'object'}}} $phpTypeSchema */
$phpTypeSchema = $this->openApiPhpTypeSchemaResolverManager
->resolvePhpTypeSchema($arrayPhpType, $phpTypeHolder);

Expand All @@ -76,8 +75,7 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
$collectionElementPhpTypeSchema = $this->openApiPhpTypeSchemaResolverManager
->resolvePhpTypeSchema($collectionElementPhpType, $phpTypeHolder);

$phpTypeSchema['oneOf'][0]['items'] = $collectionElementPhpTypeSchema;
$phpTypeSchema['oneOf'][1]['additionalProperties'] = $collectionElementPhpTypeSchema;
$phpTypeSchema['items'] = $collectionElementPhpTypeSchema;
}

return $phpTypeSchema;
Expand Down
16 changes: 3 additions & 13 deletions src/OpenApi/PhpTypeSchemaResolver/ArrayPhpTypeSchemaResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,7 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
$this->supportsPhpType($phpType, $phpTypeHolder) or throw new UnsupportedPhpTypeException();

$phpTypeSchema = [
'oneOf' => [
[
'type' => Type::OAS_TYPE_NAME_ARRAY,
],
[
'type' => Type::OAS_TYPE_NAME_OBJECT,
],
],
'type' => Type::OAS_TYPE_NAME_ARRAY,
];

if (
Expand All @@ -75,12 +68,9 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
$arrayElementPhpTypeSchema = $this->openApiPhpTypeSchemaResolverManager
->resolvePhpTypeSchema($arrayElementPhpType, $phpTypeHolder);

$phpTypeSchema['oneOf'][0]['items'] = $arrayElementPhpTypeSchema;
$phpTypeSchema['oneOf'][1]['additionalProperties'] = $arrayElementPhpTypeSchema;

$phpTypeSchema['items'] = $arrayElementPhpTypeSchema;
if ($annotation->limit !== null) {
$phpTypeSchema['oneOf'][0]['maxItems'] = $annotation->limit;
$phpTypeSchema['oneOf'][1]['maxProperties'] = $annotation->limit;
$phpTypeSchema['maxItems'] = $annotation->limit;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
namespace Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver;

use BackedEnum;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionEnum;
use ReflectionException;
use Reflector;
use Sunrise\Http\Router\OpenApi\Annotation\SchemaName;
use Sunrise\Http\Router\OpenApi\Exception\UnsupportedPhpTypeException;
use Sunrise\Http\Router\OpenApi\OpenApiPhpTypeSchemaNameResolverInterface;
use Sunrise\Http\Router\OpenApi\OpenApiPhpTypeSchemaResolverInterface;
Expand All @@ -26,7 +29,6 @@
use Sunrise\Http\Router\OpenApi\TypeFactory;

use function is_subclass_of;
use function strtr;

/**
* @since 3.0.0
Expand Down Expand Up @@ -79,6 +81,17 @@ public function getWeight(): int

public function resolvePhpTypeSchemaName(Type $phpType, Reflector $phpTypeHolder): string
{
return strtr($phpType->name, '\\', '.');
/** @var class-string $className */
$className = $phpType->name;
$classReflection = new ReflectionClass($className);

/** @var list<ReflectionAttribute<SchemaName>> $annotations */
$annotations = $classReflection->getAttributes(SchemaName::class);
if (isset($annotations[0])) {
$annotation = $annotations[0]->newInstance();
return $annotation->value;
}

return $classReflection->getShortName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
return [
'type' => Type::OAS_TYPE_NAME_NUMBER,
'format' => 'double',
'example' => 0.0,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): a
return [
'type' => Type::OAS_TYPE_NAME_INTEGER,
'format' => PHP_INT_SIZE === 4 ? 'int32' : 'int64',
'example' => 0,
];
}

Expand Down
15 changes: 13 additions & 2 deletions src/OpenApi/PhpTypeSchemaResolver/ObjectPhpTypeSchemaResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use ReflectionException;
use ReflectionProperty;
use Reflector;
use Sunrise\Http\Router\OpenApi\Annotation\SchemaName;
use Sunrise\Http\Router\OpenApi\Exception\UnsupportedPhpTypeException;
use Sunrise\Http\Router\OpenApi\OpenApiPhpTypeSchemaNameResolverInterface;
use Sunrise\Http\Router\OpenApi\OpenApiPhpTypeSchemaResolverInterface;
Expand All @@ -33,7 +34,6 @@

use function class_exists;
use function is_scalar;
use function strtr;

/**
* @since 3.0.0
Expand Down Expand Up @@ -126,7 +126,18 @@ public function getWeight(): int

public function resolvePhpTypeSchemaName(Type $phpType, Reflector $phpTypeHolder): string
{
return strtr($phpType->name, '\\', '.');
/** @var class-string $className */
$className = $phpType->name;
$classReflection = new ReflectionClass($className);

/** @var list<ReflectionAttribute<SchemaName>> $annotations */
$annotations = $classReflection->getAttributes(SchemaName::class);
if (isset($annotations[0])) {
$annotation = $annotations[0]->newInstance();
return $annotation->value;
}

return $classReflection->getShortName();
}

private static function isIgnoredProperty(ReflectionProperty $property): bool
Expand Down
12 changes: 10 additions & 2 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,12 @@ public function match(ServerRequestInterface $request): RouteInterface
*
* @throws InvalidArgumentException
*/
public function runRoute(RouteInterface $route, ServerRequestInterface $request): ResponseInterface
public function runRoute(RouteInterface|string $route, ServerRequestInterface $request): ResponseInterface
{
if (! $route instanceof RouteInterface) {
$route = $this->getRoute($route);
}

foreach ($route->getAttributes() as $name => $value) {
$request = $request->withAttribute($name, $value);
}
Expand Down Expand Up @@ -203,8 +207,12 @@ public function runRoute(RouteInterface $route, ServerRequestInterface $request)
*
* @throws InvalidArgumentException
*/
public function buildRoute(RouteInterface $route, array $values = [], bool $strictly = false): string
public function buildRoute(RouteInterface|string $route, array $values = [], bool $strictly = false): string
{
if (! $route instanceof RouteInterface) {
$route = $this->getRoute($route);
}

$result = RouteBuilder::buildRoute($route->getPath(), $values + $route->getAttributes());

if ($strictly && !RouteMatcher::matchRoute($this->compileRoute($route), $result)) {
Expand Down
4 changes: 2 additions & 2 deletions src/RouterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function hasRoute(string $name): bool;
*
* @since 3.0.0
*/
public function runRoute(RouteInterface $route, ServerRequestInterface $request): ResponseInterface;
public function runRoute(RouteInterface|string $route, ServerRequestInterface $request): ResponseInterface;

/**
* @param array<string, mixed> $values
Expand All @@ -57,7 +57,7 @@ public function runRoute(RouteInterface $route, ServerRequestInterface $request)
*
* @since 3.0.0
*/
public function buildRoute(RouteInterface $route, array $values = [], bool $strictly = false): string;
public function buildRoute(RouteInterface|string $route, array $values = [], bool $strictly = false): string;

/**
* @throws HttpException
Expand Down
3 changes: 3 additions & 0 deletions tests/Fixture/App/View/PageView.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Sunrise\Http\Router\Tests\Fixture\App\View;

use Sunrise\Http\Router\OpenApi\Annotation\SchemaName;

#[SchemaName('Page')]
final class PageView
{
public function __construct(
Expand Down
Loading