Passed
Push — master ( 03de76...b5c1c2 )
by Todd
32s
created

ArrayRefLookup::getArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Todd Burry <[email protected]>
4
 * @copyright 2009-2018 Vanilla Forums Inc.
5
 * @license MIT
6
 */
7
8
namespace Garden\Schema;
9
10
/**
11
 * A schema `$ref` lookup that searches arrays.
12
 *
13
 * @see https://swagger.io/docs/specification/using-ref/
14
 */
15
class ArrayRefLookup {
16
    /**
17
     * @var array|\ArrayAccess
18
     */
19
    private $array;
20
21
    /**
22
     * ArrayRefLookup constructor.
23
     *
24
     * @param array|\ArrayAccess $array The array that is searched.
25
     */
26 21
    public function __construct($array) {
27 21
        $this->array = $array;
28 21
    }
29
30
    /**
31
     * Lookup a schema based on a JSON ref.
32
     *
33
     * @param string $ref A valid JSON ref.
34
     * @return mixed|null Returns the value at the reference or **null** if the reference isn't found.
35
     * @see https://swagger.io/docs/specification/using-ref/
36
     */
37 20
    public function __invoke(string $ref) {
38 20
        $urlParts = parse_url($ref);
39 20
        if (!empty($urlParts['host']) || !empty($urlParts['path'])) {
40 2
            throw new \InvalidArgumentException("Only local schema references are supported. ($ref)", 400);
41
        }
42 18
        $fragment = $urlParts['fragment'] ?? '';
43 18
        if (strlen($fragment) === 0 || $fragment[0] !== '/') {
44 3
            throw new \InvalidArgumentException("Relative schema references are not supported. ($ref)", 400);
45
        }
46
47 15
        if ($fragment === '/') {
48 1
            return $this->array;
49
        }
50 14
        $parts = array_map([$this, 'unescape'], explode('/', substr($fragment, 1)));
51
52 14
        $value = $this->array;
53 14
        foreach ($parts as $key) {
54 14
            if (!is_string($value) && isset($value[$key])) {
55 12
                $value = $value[$key];
56
            } else {
57 14
                return null;
58
            }
59
        }
60 11
        return $value;
61
    }
62
63
    /**
64
     * Unescape a JSON reference segment.
65
     *
66
     * @param string $str The segment to unescape.
67
     * @return string Returns the unescaped string.
68
     */
69 14
    private function unescape(string $str): string {
70 14
        return str_replace(['~1', '~0'], ['/', '~'], $str);
71
    }
72
73
    /**
74
     * Get the array.
75
     *
76
     * @return array|\ArrayAccess Returns the array.
77
     */
78 5
    public function getArray() {
79 5
        return $this->array;
80
    }
81
82
    /**
83
     * Set the array.
84
     *
85
     * @param array|\ArrayAccess $array
86
     * @return $this
87
     */
88 1
    public function setArray($array) {
89 1
        $this->array = $array;
90 1
        return $this;
91
    }
92
}
93