Skip to content

Commit c98e961

Browse files
authored
Merge pull request #18 from sander3/portable-recursion-feature
Resolves #16
2 parents 9e71bf4 + f101fe8 commit c98e961

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

readme.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ After installing the package, you should publish the configuration file:
2626
$ php artisan vendor:publish --tag=gdpr-config
2727
```
2828

29-
Finally, add the `Soved\Laravel\Gdpr\Portable` trait to the `App\User` model:
29+
Finally, add the `Soved\Laravel\Gdpr\Portable` trait to the `App\User` model and implement the `Soved\Laravel\Gdpr\Contracts\Portable` contract:
3030

3131
```php
3232
<?php
@@ -36,8 +36,9 @@ namespace App;
3636
use Soved\Laravel\Gdpr\Portable;
3737
use Illuminate\Notifications\Notifiable;
3838
use Illuminate\Foundation\Auth\User as Authenticatable;
39+
use Soved\Laravel\Gdpr\Contracts\Portable as PortableContract;
3940

40-
class User extends Authenticatable
41+
class User extends Authenticatable implements PortableContract
4142
{
4243
use Portable, Notifiable;
4344
}

src/Contracts/Portable.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Soved\Laravel\Gdpr\Contracts;
4+
5+
interface Portable
6+
{
7+
/**
8+
* Convert the model instance to a GDPR compliant data portability array.
9+
*
10+
* @return array
11+
*/
12+
public function portable();
13+
14+
/**
15+
* Get the GDPR compliant data portability array for the model.
16+
*
17+
* @return array
18+
*/
19+
public function toPortableArray();
20+
}

src/Portable.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Soved\Laravel\Gdpr;
44

5+
use Soved\Laravel\Gdpr\Contracts\Portable as PortableContract;
6+
57
trait Portable
68
{
79
/**
@@ -13,7 +15,7 @@ public function portable()
1315
{
1416
// Eager load the given relations
1517
if (isset($this->gdprWith)) {
16-
$this->loadMissing($this->gdprWith);
18+
$this->loadRelations($this->gdprWith);
1719
}
1820

1921
// Make the given attributes visible
@@ -29,6 +31,56 @@ public function portable()
2931
return $this->toPortableArray();
3032
}
3133

34+
/**
35+
* Eager load the given relations.
36+
*
37+
* @param array $relations
38+
* @return void
39+
*/
40+
public function loadRelations(array $relations)
41+
{
42+
$portableRelations = $this->getPortableRelations($relations);
43+
44+
array_walk($portableRelations, [$this, 'loadPortableRelation']);
45+
46+
$this->load(array_diff($relations, $portableRelations));
47+
}
48+
49+
/**
50+
* Get all portable relations.
51+
*
52+
* @param array $relations
53+
* @return array
54+
*/
55+
private function getPortableRelations(array $relations)
56+
{
57+
$portableRelations = [];
58+
59+
foreach ($relations as $relation) {
60+
if ($this->$relation()->getRelated() instanceof PortableContract) {
61+
$portableRelations[] = $relation;
62+
}
63+
}
64+
65+
return $portableRelations;
66+
}
67+
68+
/**
69+
* Load and transform a portable relation.
70+
*
71+
* @param string $relation
72+
* @return void
73+
*/
74+
private function loadPortableRelation(string $relation)
75+
{
76+
$this->attributes[$relation] = $this
77+
->$relation()
78+
->get()
79+
->transform(function ($item) {
80+
return $item->portable();
81+
});
82+
}
83+
3284
/**
3385
* Get the GDPR compliant data portability array for the model.
3486
*

0 commit comments

Comments
 (0)