Completed
Push — master ( c5aab2...37e055 )
by Matt
11:55
created

Reference::resolveExternalReference()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace League\JsonGuard;
4
5
use Closure;
6
7
/**
8
 * A Reference object represents an internal $ref in a JSON object.
9
 * Because JSON references can be circular, in-lining the reference is
10
 * impossible.  This object can be substituted for the $ref instead,
11
 * allowing lazy resolution of the $ref when needed.
12
 */
13
class Reference implements \JsonSerializable
14
{
15
    /**
16
     * A JSON object resulting from a json_decode call or a Closure.
17
     * If a closure is used it should resolve to a JSON object when called.
18
     *
19
     * @var object|Closure
20
     */
21
    private $schema;
22
23
    /**
24
     * A valid JSON reference.  The reference should point to a location in $schema.
25
     * @see https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
26
     *
27
     * @var string
28
     */
29
    private $ref;
30
31
    /**
32 42
     * @param object|Closure $schema
33
     * @param string         $ref
34 42
     */
35 42
    public function __construct($schema, $ref)
36 42
    {
37
        $this->schema = $schema;
38
        $this->ref    = $ref;
39
    }
40
41
    /**
42
     * Specify data which should be serialized to JSON.
43
     * Because a reference can be circular, references are always
44
     * re-serialized as the reference property instead of attempting
45
     * to inline the data.
46
     *
47
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
48 4
     *
49
     * @return mixed data which can be serialized by <b>json_encode</b>,
50 4
     * which is a value of any type other than a resource.
51
     */
52
    public function jsonSerialize()
53
    {
54
        return ['$ref' => $this->ref];
55
    }
56
57
    /**
58 38
     * Resolve the reference and return the data.
59
     *
60 38
     * @return mixed
61 38
     */
62 38
    public function resolve()
63
    {
64
        if ($this->schema instanceof Closure) {
65
            return $this->resolveExternalReference();
66
        }
67
        return $this->resolveInternalReference();
68
    }
69
70
    /**
71
     * Resolve an external reference and return the resolved schema.
72 6
     *
73
     * @return mixed The resolved schema
74 6
     */
75 6
    private function resolveExternalReference()
76 6
    {
77
        return call_user_func($this->schema);
78
    }
79
80
    /**
81
     * Resolve an internal reference and return the resolved schema.
82
     *
83
     * @return mixed The resolved schema
84
     */
85
    private function resolveInternalReference()
86
    {
87
        $path    = trim($this->ref, '#');
88
        $pointer = new Pointer($this->schema);
89
        return $pointer->get($path);
90
    }
91
92
    /**
93
     * Proxies property access to the underlying schema.
94
     *
95
     * @param  string $property
96
     *
97
     * @return mixed
98
     *
99
     * @throws \InvalidArgumentException
100
     */
101
    public function __get($property)
102
    {
103
        $schema = $this->resolve();
104
        if (isset($schema->$property)) {
105
            return $schema->$property;
106
        }
107
108
        throw new \InvalidArgumentException(sprintf('Unknown property "%s"', $property));
109
    }
110
}
111