Skip to content

Commit 141981c

Browse files
samizdamn.gnato
andauthored
Play with php versions on build local image, psr/http-message 2 (#28)
* Add CacheableDispatcherFactoryProxy * Update packages (#24) * Remove unused import * Up cebe/php-openapi * rollback cebe/php-openapi (cebe/php-openapi#97) * Allow lowest fig/http-message-util version * Allow 0.15 league/openapi-psr7-validator versions * Allow 0.16 league/openapi-psr7-validator versions * Allow psr/cache v2 * Allow psr/cache v3 * Use helmich/phpunit-psr7-assert v4 * Add git to docker image for install composer packages from source * Add missing dependency psr/container * Remove unused dependency from doctrine * Add doctrine/persistence dependency Co-authored-by: n.gnato <[email protected]> * Union types support (#25) * Remove unused import * Support union types for relationships dto * Split testsuites by php versions * Add test case without union types * Use php version var for docker * Check union types case first * Fix typo in const name * Extract common resource examples * Update docs * Suggest nyholm/psr7 package * Exclude cebe/php-openapi versions affected by cebe/php-openapi#97 (#26) * Add actual php versions to gitlab action matrix (#27) * Add actual php versions to gitlab action matrix * Downgrade cebe/openapi version: get issue after 1.6 with null nullable. * drop php 7.4 support * Change dependencies constraints * replace cebe/php-openapi with league/openapi-psr7-validator used fork * Replace neomerx/json-api with laravel-json-api maintained fork, update ramsey/uuid to php 8.1 support version, fix warnings in test * Allow doctrine usage 3 * Play with php versions on build local image, psr/http-message 2 * Add php 8.4 to test matrix * Add inherited return types to ServiceRequestDecorator * Update supported php versions and phpunit --------- Co-authored-by: n.gnato <[email protected]>
1 parent 21712f5 commit 141981c

30 files changed

+334
-84
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ jobs:
77
strategy:
88
matrix:
99
php:
10-
- 7.4
11-
- 8.0
10+
- 8.1
11+
- 8.2
12+
- 8.3
13+
- 8.4
1214
prefer:
1315
- lowest
1416
- stable

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
/.env
2+
13
/.idea/
24

3-
/.phpunit.result.cache
5+
/.phpunit.cache/
46

57
/composer.lock
68

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
### Added
1010
- Data Transfer Object classes generation from swagger spec
1111
- JsonApiResponseFactory::createResponse() `meta` and `links` arguments
12+
- CacheableDispatcherFactoryProxy
13+
- Union types support for `data.relationships` DTO: use suitable type for input data structure
14+
15+
### Changed
16+
- Best composer dependencies compatibility: allow more versions
17+
18+
## Removed
19+
- php 7.4 and 8.0 support
1220

1321
## [0.0.14] - 2021-02-02
1422
### Added
@@ -17,7 +25,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1725
- JsonApiResponseFactory::createRelationshipResponse()
1826
- RateLimitMiddleware and related packages
1927

20-
2128
## [0.0.13] - 2021-01-27
2229
### Added
2330
- TraceIntoDetailsExplainingErrorFactory for catched ErrorHandler exceptions debug. Note: not for production usage

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
FROM php:8-cli
1+
ARG PHP_VERSION=8.3
2+
3+
FROM php:${PHP_VERSION}-cli
24

35
RUN apt-get update \
46
&& apt-get install -y \

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
PATH := $(shell pwd)/bin:$(PATH)
2+
$(shell cp -n dev.env .env)
3+
include .env
24

35
build:
4-
docker build -t free-elephants/json-api-php-toolkit .
6+
docker build --build-arg PHP_VERSION=$(PHP_VERSION) -t free-elephants/json-api-php-toolkit .
57

68
install: build
79
composer install

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,9 @@ Available in [/docs](/docs).
2828
1. [Serialize doctrine entities](/docs/doctrine.md)
2929
1. [DTO from psr server request](/docs/dto-psr7.md)
3030
1. [Validation](/docs/validation.md)
31+
32+
## Development
33+
34+
All dev env is dockerized. Your can use make receipts and `bin/` scripts without locally installed php, composer.
35+
36+
For run tests with different php version change `PHP_VERSION` value in .env and rebuild image with `make build`.

composer.json

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,34 @@
1414
"require": {
1515
"ext-intl": "*",
1616
"ext-json": "*",
17-
"cebe/php-openapi": "1.4.*",
18-
"fig/http-message-util": "^1.1",
17+
"devizzent/cebe-php-openapi": "^1.0",
18+
"doctrine/persistence": "^2.0|^3.0",
19+
"fig/http-message-util": "^1.0",
1920
"free-elephants/i18n": "^0.0.1",
2021
"laminas/laminas-stratigility": "^3.2",
21-
"league/openapi-psr7-validator": "0.14",
22-
"neomerx/json-api": "^4.0",
22+
"laravel-json-api/neomerx-json-api": "^5.0.2",
23+
"league/openapi-psr7-validator": "0.19 - 0.22",
2324
"nette/php-generator": "^3.4",
2425
"nikic/fast-route": "^1.3",
25-
"psr/cache": "^1.0",
26+
"psr/cache": "^1|^2|^3",
27+
"psr/container": "^1|^2",
2628
"psr/http-factory": "^1.0",
27-
"psr/http-message": "^1.0",
29+
"psr/http-message": "^1.0|^2.0",
2830
"psr/http-server-handler": "^1.0",
2931
"psr/http-server-middleware": "^1.0",
3032
"rakit/validation": "^1.2",
31-
"ramsey/uuid": "^3.0|^4.0"
33+
"ramsey/uuid": "^3.9.7|^4.0"
3234
},
3335
"require-dev": {
34-
"doctrine/orm": "^2.7",
35-
"helmich/phpunit-psr7-assert": "dev-master#c7c75e8",
36+
"helmich/phpunit-psr7-assert": "^4",
3637
"nyholm/psr7": "^1.2",
37-
"phpunit/phpunit": "^9.0"
38+
"phpunit/phpunit": "^10.5.38|^11.0"
3839
},
3940
"suggest": {
4041
"doctrine/orm": "^2.7",
4142
"free-elephants/di": "*",
42-
"laminas/laminas-httphandlerrunner": "*"
43+
"laminas/laminas-httphandlerrunner": "*",
44+
"nyholm/psr7": "^1.2"
4345
},
4446
"autoload": {
4547
"psr-4": {

dev.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PHP_VERSION=8.3

docs/dto-psr7.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
Full typed objects from request or response body.
44

55
See example in [test](/tests/FreeElephants/JsonApiToolkit/DTO/DocumentTest.php).
6+
7+
Union types support for relationships in PHP 8.

docs/routing.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,8 @@ JSON
6060

6161
(new DispatcherFactory(null, new Parsers\JsonFileParser()))->buildDispatcher('swagger.json');
6262
```
63+
64+
## About performance
65+
66+
Parse large swagger files have performance issues. Use `FreeElephants\JsonApiToolkit\Routing\FastRoute\CacheableDispatcherFactoryProxy` for production usage: it based on psr/cache component compare swagger file hash.
67+

phpunit.xml.dist

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
3-
<coverage processUncoveredFiles="true">
4-
<include>
5-
<directory suffix=".php">src/</directory>
6-
</include>
7-
<report>
8-
<html outputDirectory="_coverage" lowUpperBound="70" highLowerBound="99"/>
9-
<text outputFile="php://stdout"/>
10-
</report>
11-
</coverage>
12-
<php>
13-
<ini name="error_reporting" value="E_ALL"/>
14-
</php>
15-
<testsuites>
16-
<testsuite name="JsonApi Toolkit Tests">
17-
<directory>./tests</directory>
18-
</testsuite>
19-
</testsuites>
20-
<logging/>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
cacheDirectory=".phpunit.cache"
6+
executionOrder="depends,defects"
7+
requireCoverageMetadata="false"
8+
beStrictAboutCoverageMetadata="true"
9+
beStrictAboutOutputDuringTests="true"
10+
displayDetailsOnPhpunitDeprecations="true"
11+
failOnPhpunitDeprecation="true"
12+
failOnRisky="true"
13+
failOnWarning="true">
14+
<testsuites>
15+
<testsuite name="default">
16+
<directory>tests</directory>
17+
</testsuite>
18+
</testsuites>
19+
20+
<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
21+
<include>
22+
<directory>src</directory>
23+
</include>
24+
</source>
25+
26+
27+
<coverage includeUncoveredFiles="true">
28+
<report>
29+
<html outputDirectory="_coverage" lowUpperBound="70" highLowerBound="99"/>
30+
<text outputFile="php://stdout"/>
31+
</report>
32+
</coverage>
33+
2134
</phpunit>

src/FreeElephants/JsonApiToolkit/DTO/AbstractDocument.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace FreeElephants\JsonApiToolkit\DTO;
44

55
use Psr\Http\Message\MessageInterface;
6-
use Psr\Http\Message\ServerRequestInterface;
76

87
/**
98
* @property AbstractResourceObject|mixed $data

src/FreeElephants/JsonApiToolkit/DTO/AbstractResourceObject.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace FreeElephants\JsonApiToolkit\DTO;
44

5+
use FreeElephants\JsonApiToolkit\DTO\Reflection\SuitableRelationshipsTypeDetector;
6+
57
/**
6-
* @property AbstractAttributes $attributes
8+
* @property AbstractAttributes $attributes
79
* @property AbstractRelationships $relationships
810
*/
911
class AbstractResourceObject
@@ -25,10 +27,20 @@ public function __construct(array $data)
2527
}
2628

2729
if (property_exists($this, 'relationships')) {
30+
$relationshipsData = $data['relationships'];
2831
$concreteClass = new \ReflectionClass($this);
2932
$relationshipsProperty = $concreteClass->getProperty('relationships');
30-
$relationshipsClass = $relationshipsProperty->getType()->getName();
31-
$this->relationships = new $relationshipsClass($data['relationships']);
33+
$reflectionType = $relationshipsProperty->getType();
34+
35+
// handle php 8 union types
36+
if ($reflectionType instanceof \ReflectionUnionType) {
37+
$relationshipsClass = (new SuitableRelationshipsTypeDetector())->detect($reflectionType, $relationshipsData);
38+
} else {
39+
$relationshipsClass = $reflectionType->getName();
40+
}
41+
42+
$relationshipsDto = new $relationshipsClass($relationshipsData);
43+
$this->relationships = $relationshipsDto;
3244
}
3345
}
3446
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace FreeElephants\JsonApiToolkit\DTO\Reflection;
4+
5+
class SuitableRelationshipsTypeDetector
6+
{
7+
8+
public function detect(\ReflectionUnionType $propertyUnionType, array $data): ?string
9+
{
10+
foreach ($propertyUnionType->getTypes() as $type) {
11+
$candidateType = $type->getName();
12+
$candidateClass = new \ReflectionClass($candidateType);
13+
$isCandidate = false;
14+
foreach ($data as $propertyName => $propertyData) {
15+
if (!$candidateClass->hasProperty($propertyName)) {
16+
break;
17+
}
18+
$isCandidate = true;
19+
}
20+
if ($isCandidate) {
21+
break;
22+
}
23+
}
24+
25+
return $candidateType;
26+
}
27+
}

0 commit comments

Comments
 (0)