Passed
Push — master ( 30f9f9...7fa371 )
by Anton
01:59 queued 13s
created

ResourceTrait::getAllowDeletingResources()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * @author Anton Tuyakhov <[email protected]>
4
 */
5
6
namespace tuyakhov\jsonapi;
7
8
use yii\base\Arrayable;
9
use yii\db\ActiveRecordInterface;
10
use yii\web\Link;
11
use yii\web\Linkable;
12
13
trait ResourceTrait
14
{
15
    /**
16
     * @var bool a flag that enables/disables deleting of the model that contains the foreign key when setting relationships
17
     * By default the model's foreign key will be set `null` and saved.
18
     */
19
    protected $allowDeletingResources = false;
20
21
    /**
22
     * @return string
23
     */
24
    public function getId()
25
    {
26
        return (string) ($this instanceof ActiveRecordInterface ? $this->getPrimaryKey() : null);
27
    }
28
29
    /**
30
     * @return string
31
     */
32
    public function getType()
33
    {
34
        $reflect = new \ReflectionClass($this);
35
        $className = $reflect->getShortName();
36
        return Inflector::camel2id($className);
37
    }
38
39
    /**
40
     * @param array $fields
41
     * @return array
42
     */
43
    public function getResourceAttributes(array $fields = [])
44
    {
45
        $attributes = [];
46
        if ($this instanceof Arrayable) {
47
            $fieldDefinitions = $this->fields();
48
        } else {
49
            $vars = array_keys(\Yii::getObjectVars($this));
50
            $fieldDefinitions = array_combine($vars, $vars);
51
        }
52
53
        foreach ($this->resolveFields($fieldDefinitions, $fields) as $name => $definition) {
0 ignored issues
show
Bug introduced by
It seems like $fieldDefinitions can also be of type false; however, parameter $fields of tuyakhov\jsonapi\ResourceTrait::resolveFields() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
        foreach ($this->resolveFields(/** @scrutinizer ignore-type */ $fieldDefinitions, $fields) as $name => $definition) {
Loading history...
54
            $attributes[$name] = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $name);
55
        }
56
        return $attributes;
57
    }
58
59
    /**
60
     * @param array $linked
61
     * @return array
62
     */
63
    public function getResourceRelationships(array $linked = [])
64
    {
65
        $fields = [];
66
        if ($this instanceof Arrayable) {
67
            $fields = $this->extraFields();
68
        }
69
        $resolvedFields = $this->resolveFields($fields);
70
        $keys = array_keys($resolvedFields);
71
72
        $relationships = array_fill_keys($keys, null);
73
        $linkedFields = array_intersect($keys, $linked);
74
75
        foreach ($linkedFields as $name) {
76
            $definition = $resolvedFields[$name];
77
            $relationships[$name] = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $name);
78
        }
79
80
        return $relationships;
81
    }
82
83
    /**
84
     * @param string $name the case sensitive name of the relationship.
85
     * @param array|ActiveRecordInterface $relationship
86
     */
87
    public function setResourceRelationship($name, $relationship)
88
    {
89
        /** @var $this ActiveRecordInterface */
90
        if (!$this instanceof ActiveRecordInterface) {
0 ignored issues
show
introduced by
$this is always a sub-type of yii\db\ActiveRecordInterface.
Loading history...
91
            return;
92
        }
93
        if (!is_array($relationship)) {
94
            $relationship = [$relationship];
95
        }
96
        $this->unlinkAll($name, $this->allowDeletingResources);
0 ignored issues
show
Bug introduced by
Accessing allowDeletingResources on the interface yii\db\ActiveRecordInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Bug introduced by
The method unlinkAll() does not exist on yii\db\ActiveRecordInterface. Did you maybe mean unlink()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
        $this->/** @scrutinizer ignore-call */ 
97
               unlinkAll($name, $this->allowDeletingResources);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
97
        foreach ($relationship as $key => $value) {
98
            if ($value instanceof ActiveRecordInterface) {
99
                $this->link($name, $value);
100
            }
101
        }
102
    }
103
104
    /**
105
     * @param string $name the case sensitive name of the relationship.
106
     * @return array
107
     */
108
    public function getRelationshipLinks($name)
109
    {
110
        if (!$this instanceof Linkable) {
111
            return [];
112
        }
113
        $primaryLinks = $this->getLinks();
114
        if (!array_key_exists(Link::REL_SELF, $primaryLinks)) {
115
            return [];
116
        }
117
        $resourceLink = is_string($primaryLinks[Link::REL_SELF]) ? rtrim($primaryLinks[Link::REL_SELF], '/') : null;
118
        if (!$resourceLink) {
119
            return [];
120
        }
121
        return [
122
            Link::REL_SELF => "{$resourceLink}/relationships/{$name}",
123
            'related' => "{$resourceLink}/{$name}",
124
        ];
125
    }
126
127
    /**
128
     * @param array $fields
129
     * @param array $fieldSet
130
     * @return array
131
     */
132
    protected function resolveFields(array $fields, array $fieldSet = [])
133
    {
134
        $result = [];
135
136
        foreach ($fields as $field => $definition) {
137
            if (is_int($field)) {
138
                $field = $definition;
139
            }
140
            $field = Inflector::camel2id(Inflector::variablize($field), '_');
141
            if (empty($fieldSet) || in_array($field, $fieldSet, true)) {
142
                $result[$field] = $definition;
143
            }
144
        }
145
146
        return $result;
147
    }
148
149
    /**
150
     * @param $value boolean
151
     */
152
    public function setAllowDeletingResources($value)
153
    {
154
        $this->allowDeletingResources = $value;
155
    }
156
157
    /**
158
     * @return bool
159
     */
160
    public function getAllowDeletingResources()
161
    {
162
        return $this->allowDeletingResources;
163
    }
164
}
165