Skip to content

Commit 04c7cac

Browse files
committed
Update from internal 0.16 release
1 parent 28b98ac commit 04c7cac

File tree

71 files changed

+2016
-417
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2016
-417
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
tests/Resources/app/cache/
66
tests/Resources/app/data/
77
tests/Resources/app/logs/
8+
/var/
89
docker-compose.override.yml
910
/.php_cs.cache
11+
/var

.gitlab-ci.yml

+18-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,20 @@ ci-latest:
2525
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never --coverage-text=php://stdout --coverage-html=logs/coverage
2626
- bin/php php ../../../vendor/bin/security-checker security:check ../../../composer.lock
2727

28+
# symfony 4.2 build
29+
ci-symfony4.2:
30+
stage: test-versions
31+
tags:
32+
- docker-compose
33+
script:
34+
- cd tests/Resources/docker/
35+
- docker-compose build
36+
- docker-compose up -d
37+
- bin/composer require "symfony/framework-bundle:^4.2" "symfony/form:^4.2" "symfony/validator:^4.2" --no-interaction --no-ansi --prefer-dist
38+
- docker-compose run --no-deps --rm php composer install --no-interaction --no-ansi --prefer-dist
39+
- bin/setup_fixtures.sh
40+
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never
41+
2842
# symfony 4.1 build
2943
ci-symfony4.1:
3044
stage: test-versions
@@ -63,7 +77,7 @@ ci-symfony3.4:
6377
- docker-compose build
6478
- docker-compose up -d
6579
- mv -f ../app/config/symfony34/config.yml ../app/config/
66-
- bin/composer require "symfony/framework-bundle:^3.4" "symfony/form:^3.4" "symfony/validator:^3.4" --no-interaction --no-ansi --prefer-dist
80+
- bin/composer require "symfony/framework-bundle:^3.4" "symfony/form:^3.4" "symfony/validator:^3.4" "symfony/config:^3.4" "symfony/translation:^3.4" "symfony/http-foundation:^3.4" "symfony/http-kernel:^3.4" "symfony/twig-bundle:^3.4" --no-interaction --no-ansi --prefer-dist
6781
- docker-compose run --no-deps --rm php composer install --no-interaction --no-ansi --prefer-dist
6882
- bin/setup_fixtures.sh
6983
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never
@@ -78,7 +92,7 @@ ci-symfony3.3:
7892
- docker-compose build
7993
- docker-compose up -d
8094
- mv -f ../app/config/symfony34/config.yml ../app/config/
81-
- bin/composer require "symfony/framework-bundle:^3.3" "symfony/form:^3.3" "symfony/validator:^3.3" --no-interaction --no-ansi --prefer-dist
95+
- bin/composer require "symfony/framework-bundle:^3.3" "symfony/form:^3.3" "symfony/validator:^3.3" "symfony/config:^3.3" "symfony/translation:^3.3" "symfony/http-foundation:^3.3" "symfony/http-kernel:^3.3" "symfony/twig-bundle:^3.3" --no-interaction --no-ansi --prefer-dist
8296
- docker-compose run --no-deps --rm php composer install --no-interaction --no-ansi --prefer-dist
8397
- bin/setup_fixtures.sh
8498
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never
@@ -94,7 +108,7 @@ ci-symfony3.2:
94108
- docker-compose build
95109
- docker-compose up -d
96110
- mv -f ../app/config/symfony34/config.yml ../app/config/
97-
- bin/composer require "symfony/framework-bundle:^3.2" "symfony/form:^3.2" "symfony/validator:^3.2" --no-interaction --no-ansi --prefer-dist
111+
- bin/composer require "symfony/framework-bundle:^3.2" "symfony/form:^3.2" "symfony/validator:^3.2" "symfony/config:^3.2" "symfony/translation:^3.2" "symfony/http-foundation:^3.2" "symfony/http-kernel:^3.2" "symfony/twig-bundle:^3.2" --no-interaction --no-ansi --prefer-dist
98112
- docker-compose run --no-deps --rm php composer install --no-interaction --no-ansi --prefer-dist
99113
- bin/setup_fixtures.sh
100114
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never
@@ -110,7 +124,7 @@ ci-symfony3.1:
110124
- docker-compose build
111125
- docker-compose up -d
112126
- mv -f ../app/config/symfony34/config.yml ../app/config/
113-
- bin/composer require "symfony/framework-bundle:^3.1" "symfony/form:^3.1" "symfony/validator:^3.1" --no-interaction --no-ansi --prefer-dist
127+
- bin/composer require "symfony/framework-bundle:^3.1" "symfony/form:^3.1" "symfony/validator:^3.1" "symfony/config:^3.1" "symfony/translation:^3.1" "symfony/http-foundation:^3.1" "symfony/http-kernel:^3.1" "symfony/twig-bundle:^3.1" --no-interaction --no-ansi --prefer-dist
114128
- docker-compose run --no-deps --rm php composer install --no-interaction --no-ansi --prefer-dist
115129
- bin/setup_fixtures.sh
116130
- docker-compose run --no-deps --rm php php vendor/bin/phpunit --debug --colors=never

CHANGELOG.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## Unreleased
88

9+
## [0.16.0] 2019-02-14
10+
11+
### Added
12+
- `GenericFormModelInputHandler` can now auto-magicaly handle PHP objects using return typehints, see `GenericModelMetaData`
13+
14+
### Changed
15+
- `Trikoder\JsonApiBundle\Contracts\RepositoryInterface::save` can now return a object that is saved
16+
- InputHandlers will now throw `UnhandleableModelInputException` exceptions when input cannot be properly handled onto model
17+
18+
919
## [0.14.0] 2018-10-23
1020

1121
### Added
@@ -20,8 +30,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2030

2131
### Changed
2232
- Changed route annotation use to symfony/routing, previously was sensio/framework-extra-bundle
23-
- Added symfony/routing as dependancy on 3.4
24-
- Added "doctrine/common": "<2.9" as dependancy to cover deprication notices
33+
- Added symfony/routing as dependency on 3.4
34+
- Added "doctrine/common": "<2.9" as dependency to cover deprecation notices
2535

2636
### Removed
2737
- Removed second argument (ServiceContainer) of schema as closure definition. see [Manual](src/Resources/doc/getting_started/schema_class_map.md)

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Change log for the project can be found in changelog.md
4040

4141
## Testing
4242

43-
The whole sandbox and development enviroment is located inside project.
43+
The whole sandbox and development environment is located inside project.
4444

4545
To run tests, position yourself inside `tests/Resources/docker` and run `bin/test.sh`
4646
This will build whole docker setup, load fixtures and run all test suites.
@@ -56,15 +56,15 @@ There is also php access script `bin/php [CMD]` (eg. `bin/php bash` to enter bas
5656

5757
### Coding standards
5858

59-
When contributing to this package, you will need to adhere to our conding standards.
59+
When contributing to this package, you will need to adhere to our coding standards.
6060
They are following PSR-2 with some additional rules. To check your code during development
6161
you can use provided config for php-cs-fixer. it's in root of the project, file:
6262

6363
`.php_cs.dist`
6464

6565
**Checking your code**
6666

67-
First you need to setup test enviroment (as described in paragraph above).
67+
First you need to setup test environment (as described in paragraph above).
6868

6969
Then:
7070

@@ -73,7 +73,7 @@ Checking code:
7373
```
7474
bin/php_cs --dry-run
7575
```
76-
If you want automatic fix, just ommit ``--dry-run`:
76+
If you want automatic fix, just omit ``--dry-run`:
7777

7878
```
7979
bin/php_cs

composer.json

+8-5
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
"type": "symfony-bundle",
55
"require": {
66
"php": ">=7.0.0|>=7.1.0",
7-
"symfony/framework-bundle": ">=3.1 <5.0",
8-
"symfony/dependency-injection": ">=3.1 <5.0",
7+
"symfony/framework-bundle": ">=3.1 <5",
8+
"symfony/dependency-injection": ">=3.1 <5",
9+
"symfony/config": ">=3.1 <5",
910
"sensio/framework-extra-bundle": ">3.0|^5.1|^5.2",
11+
"symfony/http-foundation": ">=3.1 <5",
1012
"symfony/form": ">=3.1 <5.0",
11-
"symfony/routing": ">=3.1 <5.0",
13+
"symfony/routing": ">=3.1 <4.1.8",
1214
"symfony/security-bundle": "^3.1|^4.0",
13-
"symfony/translation": ">=3.1 <5.0",
15+
"symfony/translation": ">=3.1 <5",
1416
"symfony/validator": ">=3.1 <5.0",
1517
"symfony/monolog-bundle": ">=3.1 <5.0",
1618
"neomerx/json-api": "^1.0",
1719
"doctrine/orm": "^2.4",
1820
"doctrine/common": "^2",
19-
"doctrine/doctrine-bundle": "~1.6|^1.8|^1.9"
21+
"doctrine/doctrine-bundle": "~1.6|^1.8|^1.9",
22+
"ext-json": "*"
2023
},
2124
"require-dev": {
2225
"phpunit/phpunit": "^5.7",

phpunit.xml.dist

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<directory>./src/Resources/doc</directory>
3232
<directory>./tests</directory>
3333
<directory>./vendor</directory>
34+
<directory>./var</directory>
3435
<file>./src/DependencyInjection/TrikoderJsonApiExtension.php</file>
3536
</exclude>
3637
</whitelist>

src/Bridge/Doctrine/DoctrineRepository.php

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public function save($model)
6161
{
6262
$this->entityManager->persist($model);
6363
$this->entityManager->flush();
64+
65+
return $model;
6466
}
6567

6668
/**

src/CompilerPass/SchemaAutoMapCompilerPass.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public function process(ContainerBuilder $container)
2727

2828
$schemaDirScanPatterns = $config['schema_automap_scan_patterns'];
2929

30-
$schemaFilenames = $this->getSchemaFilenames($schemaDirScanPatterns);
30+
$schemaFilenames = $this->getSchemaFilenames(
31+
$this->processSchemaDirScanPatterns($schemaDirScanPatterns,
32+
$container->getParameter('kernel.project_dir'))
33+
);
3134

3235
foreach ($schemaFilenames as $schemaFilename) {
3336
// we need fqn for reflection and service definition changes
@@ -42,6 +45,15 @@ public function process(ContainerBuilder $container)
4245
}
4346
}
4447

48+
protected function processSchemaDirScanPatterns(array $schemaDirScanPatterns, string $rootDir): array
49+
{
50+
foreach ($schemaDirScanPatterns as $key => $pattern) {
51+
$schemaDirScanPatterns[$key] = $rootDir . '/' . $pattern;
52+
}
53+
54+
return $schemaDirScanPatterns;
55+
}
56+
4557
/**
4658
* @return string[]
4759
*/

src/Contracts/ModelTools/ModelInputHandlerInterface.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Trikoder\JsonApiBundle\Contracts\ModelTools;
44

5+
use Trikoder\JsonApiBundle\Services\ModelInput\UnhandleableModelInputException;
6+
57
/**
68
* Interface ModelInputHandlerInterface
79
*/
@@ -11,11 +13,12 @@ interface ModelInputHandlerInterface
1113
* @param object $model
1214
*
1315
* @return $this
14-
* TODO - check if better in contructor so it cannot be changed on runtime?
1516
*/
1617
public function forModel($model);
1718

1819
/**
20+
* @throws UnhandleableModelInputException
21+
*
1922
* @return $this
2023
*/
2124
public function handle(array $input);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Trikoder\JsonApiBundle\Contracts\ModelTools;
6+
7+
interface ModelMetaDataInterface
8+
{
9+
public function getAllFields(): array;
10+
11+
/**
12+
* @return null|string
13+
*/
14+
public function getTypeForField(string $fieldName);
15+
}

src/Contracts/RepositoryInterface.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public function getOne($id, $filter = []);
3030
* Saves model to arbitrary persistance layer
3131
*
3232
* @param object $model model to save
33-
* TODO - check return values
33+
*
34+
* @return null|object null or newly saved object
3435
*/
3536
public function save($model);
3637

src/Contracts/RequestBodyDecoderInterface.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
namespace Trikoder\JsonApiBundle\Contracts;
44

5+
use Trikoder\JsonApiBundle\Services\RequestDecoder\Exception\InvalidBodyForMethodException;
6+
57
interface RequestBodyDecoderInterface
68
{
79
/**
8-
* @param array $body
10+
* @return array
911
*
10-
* @return null|array
12+
* @throws InvalidBodyForMethodException
1113
*/
12-
public function decode(array $body = null);
14+
public function decode(string $requestMethod, array $body = []);
1315
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Trikoder\JsonApiBundle\Contracts;
6+
7+
use Trikoder\JsonApiBundle\Services\RequestDecoder\Exception\InvalidBodyForMethodException;
8+
9+
interface RequestBodyValidatorInterface
10+
{
11+
/**
12+
* @throws InvalidBodyForMethodException
13+
*/
14+
public function validate(string $requestMethod, array $body);
15+
}

src/Contracts/ResponseFactoryInterface.php

+5
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,9 @@ public function createError(string $data, Response $response = null): Response;
4040
* @param Response $response
4141
*/
4242
public function createErrorFromException(Exception $exception, Response $response = null): Response;
43+
44+
/**
45+
* @param Response $response
46+
*/
47+
public function createBadRequest(string $data, Response $response = null): Response;
4348
}

src/Controller/Traits/Actions/CreateTrait.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
use RuntimeException;
66
use Symfony\Bundle\FrameworkBundle\Routing\Router;
77
use Symfony\Component\HttpFoundation\Request;
8+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
89
use Symfony\Component\Routing\Route;
910
use Symfony\Component\Routing\RouterInterface;
1011
use Trikoder\JsonApiBundle\Contracts\Config\ConfigInterface;
1112
use Trikoder\JsonApiBundle\Contracts\ModelTools\ModelInputHandlerInterface;
1213
use Trikoder\JsonApiBundle\Contracts\ModelTools\ModelValidatorInterface;
14+
use Trikoder\JsonApiBundle\Contracts\RepositoryInterface;
1315
use Trikoder\JsonApiBundle\Contracts\ResponseFactoryInterface;
1416
use Trikoder\JsonApiBundle\Contracts\SchemaClassMapProviderInterface;
1517
use Trikoder\JsonApiBundle\Services\ModelInput\ModelValidationException;
18+
use Trikoder\JsonApiBundle\Services\ModelInput\UnhandleableModelInputException;
1619
use Trikoder\JsonApiBundle\Services\Neomerx\EncoderService;
1720

1821
/**
@@ -26,6 +29,7 @@ trait CreateTrait
2629
* @return object
2730
*
2831
* @throws ModelValidationException
32+
* @throws UnhandleableModelInputException
2933
*/
3034
protected function handleCreateModelInputFromRequest(ConfigInterface $config, $emptyModel, Request $request)
3135
{
@@ -52,6 +56,7 @@ protected function handleCreateModelInputFromRequest(ConfigInterface $config, $e
5256
$modelInput[$filesKey] = $filesValue;
5357
}
5458
}
59+
5560
$model = $handler->forModel($emptyModel)->handle($modelInput)->getResult();
5661

5762
// validate result
@@ -69,6 +74,7 @@ protected function handleCreateModelInputFromRequest(ConfigInterface $config, $e
6974
* @param object $model
7075
*
7176
* @throws ModelValidationException
77+
* @throws UnhandleableModelInputException
7278
*/
7379
protected function validateCreatedModel(ConfigInterface $config, $model)
7480
{
@@ -95,6 +101,7 @@ protected function validateCreatedModel(ConfigInterface $config, $model)
95101
* @return object
96102
*
97103
* @throws ModelValidationException
104+
* @throws UnhandleableModelInputException
98105
*/
99106
protected function createModelFromRequest(Request $request)
100107
{
@@ -111,8 +118,20 @@ protected function createModelFromRequest(Request $request)
111118

112119
$this->validateCreatedModel($config, $model);
113120

121+
/** @var RepositoryInterface $repository */
122+
$repository = $config->getApi()->getRepository();
123+
114124
// save it
115-
$config->getApi()->getRepository()->save($model);
125+
$saveResult = $repository->save($model);
126+
// if repository returned result, we take it as new model
127+
if (null !== $saveResult) {
128+
// if repository returned different class for model, we consider it error
129+
if (false === ($saveResult instanceof $model)) {
130+
throw new \LogicException(sprintf('Repository result is not a valid, expected object of type %s, got %s', \get_class($model), \get_class($saveResult)));
131+
}
132+
133+
return $saveResult;
134+
}
116135

117136
return $model;
118137
}
@@ -134,9 +153,16 @@ protected function createCreatedFromRequest(Request $request)
134153
try {
135154
$model = $this->createModelFromRequest($request);
136155
} catch (ModelValidationException $modelValidationException) {
137-
// TODO this should return conflict response (similar to DataResponse) or HttConflictException
138156
$response = $responseFactory->createConflict($encoder->encodeErrors($modelValidationException->getViolations()));
139157

158+
return $response;
159+
} catch (UnhandleableModelInputException $unhandleableModelInputException) {
160+
if ($unhandleableModelInputException->getPrevious() instanceof ModelValidationException && $unhandleableModelInputException->getPrevious()->hasViolations()) {
161+
$response = $responseFactory->createConflict($encoder->encodeErrors($unhandleableModelInputException->getPrevious()->getViolations()));
162+
} else {
163+
$response = $responseFactory->createErrorFromException(new BadRequestHttpException($unhandleableModelInputException->getMessage()));
164+
}
165+
140166
return $response;
141167
}
142168

0 commit comments

Comments
 (0)