Issues (26)

src/Metadata/Field.php (1 issue)

Labels
Severity
1
<?php namespace JSONAPI\Resource\Metadata;
2
3
use JSONAPI\Resource\Attributes\AbstractFieldAttribute;
4
5
use JSONAPI\Resource\Metadata\Exceptions\ClassesNotMatchException;
6
use JSONAPI\Resource\Metadata\Exceptions\KeyMissingException;
7
use JSONAPI\Resource\Metadata\Exceptions\ValueMissingException;
8
use ReflectionMethod;
9
use ReflectionProperty;
10
use Reflector;
11
12
/**
13
 * Wrapper around the "Attribute" attribute.
14
 * Represents specific resource JSONAPI attribute.
15
 */
16
class Field
17
{
18
    public function __construct(
19
        protected AbstractFieldAttribute $attribute,
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_PROTECTED, expecting T_VARIABLE on line 19 at column 8
Loading history...
20
        protected Reflector $reflection
21
    ) {}
22
23
    /**
24
     * @return array<string, mixed>
25
     */
26
    public function getOptions(): array
27
    {
28
        return $this->attribute->getOptions();
29
    }
30
31
    /**
32
     * Returns attribute key in JSON:API resource presentation: data.attribute.{key}
33
     *
34
     * @return string
35
     */
36
    public function getKey(): string
37
    {
38
        if (null !== ($key = $this->attribute->getKey())) {
39
            return $key;
40
        }
41
42
        if ($this->reflection instanceof ReflectionMethod) {
43
            return $this->reflection->getName();
44
        }
45
46
        if ($this->reflection instanceof ReflectionProperty) {
47
            return $this->reflection->getName();
48
        }
49
50
        throw new KeyMissingException('Unable to get key. Probably key not provided for class target.');
51
    }
52
53
    /**
54
     * Method used for fetching attribute value from JSON:API resource.
55
     */
56
    public function getValue(object $resource): mixed
57
    {
58
        if (null !== ($value = $this->attribute->getValue())) {
59
            return is_callable($value) ? $value($resource, $this) : $value;
60
        }
61
62
        if ($this->reflection instanceof ReflectionMethod) {
63
            if (!$this->reflection->getDeclaringClass()->isInstance($resource)) {
64
                throw new ClassesNotMatchException(sprintf(
65
                    'Provided resource "%s" do not match field\'s parent class "%s"',
66
                    get_class($resource),
67
                    $this->reflection->getDeclaringClass()->getName()
68
                ));
69
            }
70
71
            return $this->reflection->invoke($resource);
72
        }
73
74
        if ($this->reflection instanceof ReflectionProperty) {
75
            return $this->reflection->getValue($resource);
76
        }
77
78
        throw new ValueMissingException('Unable to get value. Probably value not provided for class target.');
79
    }
80
}