8000 Merge branch '1.x' into develop · CodingSeo/laravel-json-api@71bd6c9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 71bd6c9

Browse files
committed
Merge branch '1.x' into develop
Closes cloudcreativity#503
2 parents 2b733f5 + 7200fd6 commit 71bd6c9

File tree

18 files changed

+562
-17
lines changed

18 files changed

+562
-17
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
All notable changes to this project will be documented in this file. This project adheres to
33
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
44

5+
## Unreleased
6+
7+
### Added
8+
- [#503](https://github.com/cloudcreativity/laravel-json-api/issues/503)
9+
The JSON API `hasOne` relation now also supports an Eloquent `morphOne` relation.
10+
511
## [2.0.0-beta.2] - 2020-04-12
612

713
### Changed
@@ -79,6 +85,15 @@ were removed.
7985
- `Utils\Pointer`
8086
- `Utils\Replacer`
8187

88+
## [1.7.0] - 2020-04-13
89+
90+
### Added
91+
- [#503](https://github.com/cloudcreativity/laravel-json-api/issues/503)
92+
The JSON API `hasOne` relation now also supports an Eloquent `morphOne` relation.
93+
94+
### Changed
95+
- Minimum Laravel version is now `5.8` (previously `5.5`).
96+
8297
## [1.6.0] - 2020-01-13
8398

8499
### Added

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ A demo application is available at [here](https://github.com/cloudcreativity/dem
6262

6363
| Laravel | This Package |
6464
| --- | --- |
65-
| `^7.0` | `2.0.0-beta.1` |
66-
| `^6.0` | `^1.0` |
67-
| `5.8.*` | `^1.0` |
65+
| `^7.0` | `^2.0` (currently `beta` releases) |
66+
| `^6.0` | `^1.7` |
67+
| `5.8.*` | `^1.7` |
6868
| `5.7.*` | `^1.0` |
6969
| `5.6.*` | `^1.0` |
7070
| `5.5.*` | `^1.0` |

docs/basics/adapters.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ for Eloquent models. The relationship types available are `belongsTo`, `hasOne`,
230230
| `belongsToMany` | `hasMany` |
231231
| `hasManyThrough` | `hasManyThrough` |
232232
| `morphTo` | `belongsTo` |
233+
| `morphOne` | `hasOne` |
233234
| `morphMany` | `hasMany` |
234235
| `morphToMany` | `hasMany` |
235236
| `morphedByMany` | `morphMany` |
@@ -512,7 +513,7 @@ in user. In this case, you would only ever want resources owned by that user to
512513
from the client's perspective, any resources belonging to other users do not exist. In this case, a global
513514
scope would ensure that a `404 Not Found` is returned for resources that belong to other users.
514515

515-
> In contrast, if your API serves a mixture of resources belonging to different users, then
516+
> In contrast, if your API serves a mixture of resources belonging to different users, then
516517
`401 Unauthorized` or `403 Forbidden` responses might be more appropriate when attempting to access other
517518
users' resources. In this scenario, [Authorizers](./security.md) would be a better approach than global
518519
scopes.
@@ -610,10 +611,10 @@ class DummyClass extends AbstractResourceAdapter
610611
{
611612
// TODO: Implement persist() method.
612613
}
613-
614+
614615
/**
615616
* @inheritDoc
616-
*/
617+
*/
617618
protected function destroy($record)
618619
{
619620
// TODO: Implement destroy() method.
@@ -704,15 +705,15 @@ on our adapter:
704705
class Adapter extends AbstractAdapter
705706
{
706707
// ...
707-
708+
708709
protected function creating(Comment $comment): void
709710
{
710711
$comment->createdBy()->associate(Auth::user());
711712
}
712713
}
713714
```
714715

715-
> If your resource uses a [client-generated ID](../crud/creating.md#client-generated-ids), you
716+
> If your resource uses a [client-generated ID](../crud/creating.md#client-generated-ids), you
716717
will need to use the `creating` hook to assign the id to the model.
717718

718719
There are two additional hooks that are invoked when an adapter is deleting a resource: `deleting` and `deleted`.

src/Eloquent/HasOne.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function update($record, array $relationship, EncodingParametersInterface
4141

4242
/** If there is a current related model, we need to clear it. */
4343
if ($current) {
44-
$current->setAttribute($relation->getForeignKeyName(), null)->save();
44+
$this->clear($current, $relation);
4545
}
4646

4747
/** If there is a related model, save it. */
@@ -68,6 +68,25 @@ public function replace($record, array $relationship, EncodingParametersInterfac
6868
*/
6969
protected function acceptRelation($relation)
7070
{
71-
return $relation instanceof Relations\HasOne;
71+
if ($relation instanceof Relations\HasOne) {
72+
return true;
73+
}
74+
75+
return $relation instanceof Relations\MorphOne;
76+
}
77+
78+
/**
79+
* Clear the relation.
80+
*
81+
* @param Model $current
82+
* @param $relation
83+
*/
84+
private function clear(Model $current, $relation)
85+
{
86+
if ($relation instanceof Relations\MorphOne) {
87+
$current->setAttribute($relation->getMorphType(), null);
88+
}
89+
90+
$current->setAttribute($relation->getForeignKeyName(), null)->save();
7291
}
7392
}

tests/dummy/app/Image.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace DummyApp;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Database\Eloquent\Relations\MorphTo;
7+
8+
class Image extends Model
9+
{
10+
11+
/**
12+
* @return MorphTo
13+
*/
14+
public function imageable()
15+
{
16+
return $this->morphTo();
17+
}
18+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright 2020 Cloud Creativity Limited
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
namespace DummyApp\JsonApi\Images;
19+
20+
use CloudCreativity\LaravelJsonApi\Eloquent\AbstractAdapter;
21+
use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy;
22+
use DummyApp\Image;
23+
use Illuminate\Database\Eloquent\Builder;
24+
use Illuminate\Support\Collection;
25+
26+
class Adapter extends AbstractAdapter
27+
{
28+
29+
/**
30+
* Mapping of JSON API attribute field names to model keys.
31+
*
32+
* @var array
33+
*/
34+
protected $attributes = [];
35+
36+
/**
37+
* Mapping of JSON API filter names to model scopes.
38+
*
39+
* @var array
40+
*/
41+
protected $filterScopes = [];
42+
43+
/**
44+
* Adapter constructor.
45+
*
46+
* @param StandardStrategy $paging
47+
*/
48+
public function __construct(StandardStrategy $paging)
49+
{
50+
parent::__construct(new Image(), $paging);
51+
}
52+
53+
/**
54+
* @param Builder $query
55+
* @param Collection $filters
56+
* @return void
57+
*/
58+
protected function filter($query, Collection $filters)
59+
{
60+
$this->filterWithScopes($query, $filters);
61+
}
62+
63+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace DummyApp\JsonApi\Images;
4+
5+
use DummyApp\Image;
6+
use Neomerx\JsonApi\Schema\SchemaProvider;
7+
8+
class Schema extends SchemaProvider
9+
{
10+
11+
/**
12+
* @var string
13+
*/
14+
protected $resourceType = 'images';
15+
16+
/**
17+
* @param Image $resource
18+
* the domain record being serialized.
19+
* @return string
20+
*/
21+
public function getId($resource)
22+
{
23+
return (string) $resource->getRouteKey();
24+
}
25+
26+
/**
27+
* @param Image $resource
28+
* the domain record being serialized.
29+
* @return array
30+
*/
31+
public function getAttributes($resource)
32+
{
33+
return [
34+
'created-at' => $resource->created_at->toAtomString(),
35+
'updated-at' => $resource->updated_at->toAtomString(),
36+
'url' => $resource->url,
37+
];
38+
}
39+
}

tests/dummy/app/JsonApi/Posts/Adapter.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use CloudCreativity\LaravelJsonApi\Eloquent\BelongsTo;
2222
use CloudCreativity\LaravelJsonApi\Eloquent\Concerns\SoftDeletesModels;
2323
use CloudCreativity\LaravelJsonApi\Eloquent\HasMany;
24+
use CloudCreativity\LaravelJsonApi\Eloquent\HasOne;
2425
use CloudCreativity\LaravelJsonApi\Eloquent\QueriesMany;
2526
use CloudCreativity\LaravelJsonApi\Eloquent\QueriesOne;
2627
use CloudCreativity\LaravelJsonApi\Pagination\StandardStrategy;
@@ -88,6 +89,14 @@ protected function comments()
8889
return $this->hasMany();
8990
}
9091

92+
/**
93+
* @return HasOne
94+
*/
95+
protected function image()
96+
{
97+
return $this->hasOne();
98+
}
99+
91100
/**
92101
* @return HasMany
93102
*/

tests/dummy/app/JsonApi/Posts/Schema.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ public function getRelationships($record, $isPrimary, array $includedRelationshi
8383
return $isPrimary ? ['count' => $record->comments()->count()] : null;
8484
},
8585
],
86+
'image' => [
87+
self::SHOW_SELF => true,
88+
self::SHOW_RELATED => true,
89+
self::SHOW_DATA => isset($includedRelationships['image']),
90+
self::DATA => function () use ($record) {
91+
return $record->image;
92+
},
93+
],
8694
'tags' => [
8795
self::SHOW_SELF => true,
8896
self::SHOW_RELATED => true,

tests/dummy/app/JsonApi/Posts/Validators.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class Validators extends AbstractValidators
5454
'author',
5555
'comments',
5656
'comments.created-by',
57+
'image',
5758
'tags',
5859
];
5960

tests/dummy/app/Post.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Illuminate\Database\Eloquent\Model;
2222
use Illuminate\Database\Eloquent\Relations\BelongsTo;
2323
use Illuminate\Database\Eloquent\Relations\MorphMany;
24+
use Illuminate\Database\Eloquent\Relations\MorphOne;
2425
use Illuminate\Database\Eloquent\Relations\MorphToMany;
2526
use Illuminate\Database\Eloquent\SoftDeletes;
2627

@@ -63,6 +64,14 @@ public function comments()
6364
return $this->morphMany(Comment::class, 'commentable');
6465
}
6566

67+
/**
68+
* @return MorphOne
69+
*/
70+
public function image()
71+
{
72+
return $this->morphOne(Image::class, 'imageable');
73+
}
74+
6675
/**
6776
* @return MorphToMany
6877
*/

tests/dummy/app/User.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use Illuminate\Database\Eloquent\Relations\BelongsTo;
2121
use Illuminate\Database\Eloquent\Relations\HasOne;
22+
use Illuminate\Database\Eloquent\Relations\MorphOne;
2223
use Illuminate\Foundation\Auth\User as Authenticatable;
2324
use Illuminate\Notifications\Notifiable;
2425

@@ -66,19 +67,27 @@ class User extends Authenticatable
6667
];
6768

6869
/**
69-
* @return HasOne
70+
* @return BelongsTo
7071
*/
71-
public function phone()
72+
public function country()
7273
{
73-
return $this->hasOne(Phone::class);
74+
return $this->belongsTo(Country::class);
7475
}
7576

7677
/**
77-
* @return BelongsTo
78+
* @return MorphOne
7879
*/
79-
public function country()
80+
public function image()
8081
{
81-
return $this->belongsTo(Country::class);
82+
return $this->morphOne(Image::class, 'imageable');
83+
}
84+
85+
/**
86+
* @return HasOne
87+
*/
88+
public function phone()
89+
{
90+
return $this->hasOne(Phone::class);
8291
}
8392

8493
/**

tests/dummy/config/json-api-v1.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
'countries' => \DummyApp\Country::class,
7272
'downloads' => \DummyApp\Download::class,
7373
'histories' => \DummyApp\History::class,
74+
'images' => \DummyApp\Image::class,
7475
'phones' => \DummyApp\Phone::class,
7576
'posts' => \DummyApp\Post::class,
7677
'sites' => \DummyApp\Entities\Site::class,

tests/dummy/database/factories/ModelFactory.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18+
use DummyApp\User;
1819
use Faker\Generator as Faker;
1920
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
2021
use Illuminate\Support\Str;
@@ -75,6 +76,13 @@
7576
];
7677
});
7778

79+
/** Image */
80+
$factory->define(DummyApp\Image::class, function (Faker $faker) {
81+
return [
82+
'url' => $faker->imageUrl(),
83+
];
84+
});
85+
7886
/** Phone */
7987
$factory->define(DummyApp\Phone::class, function (Faker $faker) {
8088
return [

0 commit comments

Comments
 (0)
0