Skip to content

Commit b77abe7

Browse files
committed
Update from internal 0.18 release
1 parent 04c7cac commit b77abe7

File tree

128 files changed

+5154
-469
lines changed

Some content is hidden

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

128 files changed

+5154
-469
lines changed

CHANGELOG.md

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

77
## Unreleased
88

9+
### Changed
10+
- Form validation errors now generate pointers from cause instead of origin
11+
12+
### Fixed
13+
- Form validation errors pointers now correctly target deep properties
14+
- Specified includes now get properly included on create requests
15+
16+
## [0.17.5] 2019-11-15
17+
18+
### Added
19+
- Added CI checks for symfony 4.3
20+
21+
### Fixed
22+
- Show routes with additional parameters now generate properly
23+
- CI checks for Symfony 3.4 now uses same version router component
24+
25+
### Changed
26+
- Show route calculations no longer use route collection but instead use convention naming
27+
- Self url calculation no longer uses route collection but instead uses current route parameters
28+
29+
## [0.17.4] 2019-10-21
30+
31+
### Added
32+
- Support for relationship editing trait, see `src/Resources/doc/flow/write_actions.md#updaterelationship`
33+
34+
### Depretacted
35+
- dropped support for symfony versions 3.1, 3.2, 3.3
36+
37+
## [0.17.3] 2019-09-16
38+
39+
### Changed
40+
- default content type in responses changed to `application/vnd.api+json`
41+
42+
## [0.17.2] 2019-08-28
43+
44+
### Fixed
45+
- Create trait uses property accessor to get ID instead of expecting getId method
46+
47+
## [0.17.1] 2019-08-22
48+
49+
### Fixed
50+
- JsonApi controller check to allow for callable
51+
- Form errors now provide correct code from violation
52+
53+
## [0.17.0] 2019-08-09
54+
55+
### Added
56+
- The `\Trikoder\JsonApiBundle\Listener\KernelListener` listener priorities for the
57+
`kernel.view` and `kernel.exception` events can now be configured via the extension's
58+
`kernel_listener_on_kernel_view_priority` and `kernel_listener_on_kernel_exception_priority`
59+
keys respectively.
60+
- `Trikoder\JsonApiBundle\Schema\Builtin\GenericSchema` to be used for exposing 1:1 any resource
61+
- `Trikoder\JsonApiBundle\Services\Client\ResponseBodyDecoder` to be used as client for jsonapi response
62+
963
## [0.16.0] 2019-02-14
1064

1165
### Added

composer.json

+23-22
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,39 @@
44
"type": "symfony-bundle",
55
"require": {
66
"php": ">=7.0.0|>=7.1.0",
7-
"symfony/framework-bundle": ">=3.1 <5",
8-
"symfony/dependency-injection": ">=3.1 <5",
9-
"symfony/config": ">=3.1 <5",
10-
"sensio/framework-extra-bundle": ">3.0|^5.1|^5.2",
11-
"symfony/http-foundation": ">=3.1 <5",
12-
"symfony/form": ">=3.1 <5.0",
13-
"symfony/routing": ">=3.1 <4.1.8",
14-
"symfony/security-bundle": "^3.1|^4.0",
15-
"symfony/translation": ">=3.1 <5",
16-
"symfony/validator": ">=3.1 <5.0",
17-
"symfony/monolog-bundle": ">=3.1 <5.0",
7+
"symfony/framework-bundle": "^3.4|^4.4",
8+
"symfony/dependency-injection": "^3.4|^4.4",
9+
"symfony/config": "^3.4|^4.4",
10+
"sensio/framework-extra-bundle": "^5.3",
11+
"symfony/http-foundation": "^3.4|^4.4",
12+
"symfony/form": "^3.4|^4.4",
13+
"symfony/routing": "^3.4|^4.4",
14+
"symfony/security-bundle": "^3.4|^4.4",
15+
"symfony/translation": "^3.4|^4.4",
16+
"symfony/validator": "^3.4|^4.4",
17+
"symfony/monolog-bundle": "^3.4",
1818
"neomerx/json-api": "^1.0",
1919
"doctrine/orm": "^2.4",
2020
"doctrine/common": "^2",
21-
"doctrine/doctrine-bundle": "~1.6|^1.8|^1.9",
22-
"ext-json": "*"
21+
"doctrine/doctrine-bundle": "^1.11|^2.0",
22+
"ext-json": "*",
23+
"symfony/property-access": "^3.4|^4.4"
2324
},
2425
"require-dev": {
2526
"phpunit/phpunit": "^5.7",
2627
"phpunit/php-code-coverage": "^4.0",
27-
"symfony/phpunit-bridge": "^3.0|^4.0",
28+
"symfony/phpunit-bridge": "^3.4|^4.4",
2829
"justinrainbow/json-schema": "^1.6",
29-
"doctrine/doctrine-fixtures-bundle": "^2.3",
30+
"doctrine/doctrine-fixtures-bundle": "^3.3",
3031
"fzaninotto/faker": "^1.5",
31-
"sensiolabs/security-checker": "^4.1",
32-
"symfony/twig-bundle": "^3.3|^4.0",
32+
"sensiolabs/security-checker": "^5",
33+
"symfony/twig-bundle": "^3.4|^4.4",
3334
"doctrine/cache": "^1.6",
34-
"symfony/debug-bundle": "^3.3|^4.0",
35-
"symfony/web-profiler-bundle": "^3.3|^4.0",
36-
"symfony/web-server-bundle": "^3.3|^4.0",
37-
"symfony/browser-kit": "^3.3|^4.0",
38-
"friendsofphp/php-cs-fixer": "2.13.0"
35+
"symfony/debug-bundle": "^3.4|^4.4",
36+
"symfony/web-profiler-bundle": "^3.4|^4.4",
37+
"symfony/web-server-bundle": "^3.4|^4.4",
38+
"symfony/browser-kit": "^3.4|^4.4",
39+
"friendsofphp/php-cs-fixer": "^2.13"
3940
},
4041
"autoload": {
4142
"psr-4": {

phpunit.xml.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<server name="KERNEL_DIR" value="tests/Resources/app" />
1212
<server name="KERNEL_CLASS" value="\AppKernel" />
1313
<!-- \Doctrine\Common\ClassLoader is deprecated in doctrine/common v2.9.0 -->
14-
<env name="SYMFONY_DEPRECATIONS_HELPER" value="1" />
14+
<env name="SYMFONY_DEPRECATIONS_HELPER" value="max[self]=0&amp;verbose=0" />
1515
</php>
1616
<testsuites>
1717
<testsuite name="Unit">

src/Bridge/Doctrine/DoctrineRepository.php

+95-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44

55
use Doctrine\ORM\EntityManager;
66
use Doctrine\ORM\EntityRepository;
7+
use Doctrine\ORM\Mapping\MappingException;
8+
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
9+
use Trikoder\JsonApiBundle\Contracts\RelationshipDoesNotExistException;
10+
use Trikoder\JsonApiBundle\Contracts\RelationshipRepositoryInterface;
711
use Trikoder\JsonApiBundle\Contracts\RepositoryInterface;
12+
use Trikoder\JsonApiBundle\Contracts\ResourceDoesNotExistException;
813

914
/**
1015
* Class DoctrineRepository
1116
*/
12-
class DoctrineRepository implements RepositoryInterface
17+
class DoctrineRepository implements RepositoryInterface, RelationshipRepositoryInterface
1318
{
1419
/**
1520
* @var EntityRepository
@@ -20,13 +25,22 @@ class DoctrineRepository implements RepositoryInterface
2025
*/
2126
protected $entityManager;
2227

28+
/**
29+
* @var PropertyAccessorInterface
30+
*/
31+
protected $propertyAccessor;
32+
2333
/**
2434
* DoctrineRepository constructor.
2535
*/
26-
public function __construct(EntityRepository $entityRepository, EntityManager $entityManager)
27-
{
36+
public function __construct(
37+
EntityRepository $entityRepository,
38+
EntityManager $entityManager,
39+
PropertyAccessorInterface $propertyAccessor
40+
) {
2841
$this->entityRepository = $entityRepository;
2942
$this->entityManager = $entityManager;
43+
$this->propertyAccessor = $propertyAccessor;
3044
}
3145

3246
/**
@@ -75,4 +89,82 @@ public function remove($model)
7589
$this->entityManager->remove($model);
7690
$this->entityManager->flush();
7791
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function addToRelationship($model, string $relationshipName, array $relationshipData)
97+
{
98+
$modelMeta = $this->entityManager->getClassMetadata($this->entityRepository->getClassName());
99+
100+
try {
101+
$relationshipModelClassName = $modelMeta->getAssociationMapping($relationshipName)['targetEntity'];
102+
} catch (MappingException $e) {
103+
throw new RelationshipDoesNotExistException($relationshipName);
104+
}
105+
106+
$relationshipModelMeta = $this->entityManager->getClassMetadata($relationshipModelClassName);
107+
$relationshipIdentifier = $relationshipModelMeta->getSingleIdentifierFieldName();
108+
109+
$repository = $this->entityManager->getRepository($relationshipModelClassName);
110+
$currentRelationshipModels = $this->propertyAccessor->getValue($model, $relationshipName);
111+
112+
$relationshipModels = [];
113+
114+
//add current relationship resources to array
115+
foreach ($currentRelationshipModels as $data) {
116+
$relationshipModels[$this->propertyAccessor->getValue($data, $relationshipIdentifier)] = $data;
117+
}
118+
119+
$newRelationshipModels = $repository->findBy([$relationshipIdentifier => array_column($relationshipData, 'id')]);
120+
121+
/*
122+
* @see https://gitlab.trikoder.net/trikoder/jsonapibundle/merge_requests/102#note_251076
123+
*/
124+
if (\count($newRelationshipModels) !== \count($relationshipData)) {
125+
throw new ResourceDoesNotExistException();
126+
}
127+
128+
//add new relationship resources to array
129+
foreach ($newRelationshipModels as $data) {
130+
$relationshipModels[$this->propertyAccessor->getValue($data, $relationshipIdentifier)] = $data;
131+
}
132+
133+
$this->propertyAccessor->setValue($model, $relationshipName, $relationshipModels);
134+
135+
return $this->save($model);
136+
}
137+
138+
/**
139+
* {@inheritdoc}
140+
*/
141+
public function removeFromRelationship($model, string $relationshipName, array $relationshipData)
142+
{
143+
$modelMeta = $this->entityManager->getClassMetadata($this->entityRepository->getClassName());
144+
145+
try {
146+
$relationshipModelClassName = $modelMeta->getAssociationMapping($relationshipName)['targetEntity'];
147+
} catch (MappingException $e) {
148+
throw new RelationshipDoesNotExistException($relationshipName);
149+
}
150+
151+
$relationshipModelMeta = $this->entityManager->getClassMetadata($relationshipModelClassName);
152+
$relationshipIdentifier = $relationshipModelMeta->getSingleIdentifierFieldName();
153+
154+
$relationshipModels = $this->propertyAccessor->getValue($model, $relationshipName);
155+
$relationshipIds = array_column($relationshipData, 'id');
156+
157+
$this->propertyAccessor->setValue(
158+
$model,
159+
$relationshipName,
160+
array_filter(
161+
iterator_to_array($relationshipModels),
162+
function ($data) use ($relationshipIdentifier, $relationshipIds) {
163+
return !\in_array($this->propertyAccessor->getValue($data, $relationshipIdentifier), $relationshipIds);
164+
}
165+
)
166+
);
167+
168+
return $this->save($model);
169+
}
78170
}

src/Bridge/Doctrine/RepositoryFactory.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Trikoder\JsonApiBundle\Bridge\Doctrine;
44

55
use Doctrine\ORM\EntityManager;
6+
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
67
use Trikoder\JsonApiBundle\Contracts\RepositoryInterface;
78
use Trikoder\JsonApiBundle\Repository\RepositoryFactoryInterface;
89

@@ -15,13 +16,15 @@ class RepositoryFactory implements RepositoryFactoryInterface
1516
* @var EntityManager
1617
*/
1718
private $entityManager;
19+
private $propertyAccessor;
1820

1921
/**
2022
* RepositoryFactory constructor.
2123
*/
22-
public function __construct(EntityManager $entityManager)
24+
public function __construct(EntityManager $entityManager, PropertyAccessorInterface $propertyAccessor)
2325
{
2426
$this->entityManager = $entityManager;
27+
$this->propertyAccessor = $propertyAccessor;
2528
}
2629

2730
/**
@@ -31,7 +34,8 @@ public function create(string $modelClass): RepositoryInterface
3134
{
3235
return new DoctrineRepository(
3336
$this->entityManager->getRepository($modelClass),
34-
$this->entityManager
37+
$this->entityManager,
38+
$this->propertyAccessor
3539
);
3640
}
3741
}

src/Config/Annotation/Config.php

+15
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ class Config
3535
*/
3636
public $requestBodyDecoder;
3737

38+
/**
39+
* @var string
40+
*/
41+
public $relationshipRequestBodyDecoder;
42+
43+
/**
44+
* @var string
45+
*/
46+
public $requestBodyValidator;
47+
3848
/**
3949
* @var bool
4050
*/
@@ -59,4 +69,9 @@ class Config
5969
* @var Trikoder\JsonApiBundle\Config\Annotation\DeleteConfig
6070
*/
6171
public $delete;
72+
73+
/**
74+
* @var Trikoder\JsonApiBundle\Config\Annotation\UpdateRelationshipConfig
75+
*/
76+
public $updateRelationship;
6277
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Trikoder\JsonApiBundle\Config\Annotation;
4+
5+
use Doctrine\Common\Annotations\Annotation;
6+
use Doctrine\Common\Annotations\Annotation\Target;
7+
8+
/**
9+
* @Annotation
10+
* @Target("ANNOTATION")
11+
*/
12+
class UpdateRelationshipConfig
13+
{
14+
/**
15+
* @return array|null
16+
*/
17+
public $allowedRelationships;
18+
19+
/**
20+
* @return array|null
21+
*/
22+
public $requiredRoles;
23+
}

0 commit comments

Comments
 (0)