Skip to content

Commit 7848aa3

Browse files
committed
Create RelationshipIterator support class
1 parent 4935196 commit 7848aa3

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

src/Serializers/RelationshipSerializer.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
namespace Huntie\JsonApi\Serializers;
44

5-
use Exception;
6-
use Huntie\JsonApi\Exceptions\InvalidRelationPathException;
5+
use Huntie\JsonApi\Support\RelationshipIterator;
76
use Illuminate\Database\Eloquent\Model;
87
use Illuminate\Support\Collection;
98

@@ -36,16 +35,7 @@ public function __construct($record, $path, array $fields = [])
3635
{
3736
parent::__construct();
3837

39-
try {
40-
$this->relation = $record;
41-
42-
foreach (explode('.', $path) as $relation) {
43-
$this->relation = $this->relation->{$relation};
44-
}
45-
} catch (Exception $e) {
46-
throw new InvalidRelationPathException($path);
47-
}
48-
38+
$this->relation = (new RelationshipIterator($record, $path))->resolve();
4939
$this->fields = array_unique($fields);
5040
}
5141

src/Support/RelationshipIterator.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Huntie\JsonApi\Support;
4+
5+
use InvalidArgumentException;
6+
use Huntie\JsonApi\Exceptions\InvalidRelationPathException;
7+
8+
class RelationshipIterator
9+
{
10+
/**
11+
* The primary record.
12+
*/
13+
private $record;
14+
15+
/**
16+
* The path to the relation.
17+
*
18+
* @var string
19+
*/
20+
private $path;
21+
22+
/**
23+
* Create a new RelationshipIterator instance.
24+
*
25+
* @param Model $record The primary record
26+
* @param string $path The path to the relation
27+
*/
28+
public function __construct($record, $path)
29+
{
30+
if (!preg_match('/[A-Za-z.]+/', $path)) {
31+
throw new InvalidArgumentException('The relationship path must be a valid string');
32+
}
33+
34+
$this->record = $record;
35+
$this->path = $path;
36+
}
37+
38+
/**
39+
* Resolve the relationship from the primary record.
40+
*
41+
* @throws InvalidRelationPathException
42+
*
43+
* @return Collection|Model|null
44+
*/
45+
public function resolve()
46+
{
47+
return array_reduce(explode('.', $this->path), function ($resolved, $relation) {
48+
if (is_null($resolved) || in_array($relation, $this->record->getHidden())) {
49+
throw new InvalidRelationPathException($this->path);
50+
}
51+
52+
return $resolved->{$relation};
53+
}, $this->record);
54+
}
55+
}

0 commit comments

Comments
 (0)