Completed
Push — standalone ( a45559...3ee90b )
by Philip
04:55
created

ClassMetadata::mergeField()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 2
crap 2
1
<?php
2
3
namespace Dontdrinkandroot\RestBundle\Metadata;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Dontdrinkandroot\RestBundle\Metadata\Annotation\Method;
7
use Metadata\MergeableClassMetadata;
8
use Metadata\MergeableInterface;
9
10
class ClassMetadata extends MergeableClassMetadata
11
{
12
    /**
13
     * @var bool
14
     */
15
    public $restResource;
16
17
    /**
18
     * @var string
19
     */
20
    public $namePrefix;
21
22
    /**
23
     * @var string
24
     */
25
    public $pathPrefix;
26
27
    /**
28
     * @var string
29
     */
30
    public $idField;
31
32
    /**
33
     * @var string
34
     */
35
    public $service;
36
37
    /**
38
     * @var string
39
     */
40
    public $controller;
41
42
    /**
43
     * @var Method[]|null
44
     */
45
    public $methods;
46
47 34
    public function __construct($name)
48
    {
49 34
        parent::__construct($name);
50
51 34
        $this->namePrefix = Inflector::tableize($this->reflection->getShortName());
52 34
        $this->pathPrefix = Inflector::pluralize(strtolower($this->reflection->getShortName()));
53 34
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 8
    public function merge(MergeableInterface $object)
59
    {
60 8
        if (!$object instanceof MergeableClassMetadata) {
61
            throw new \InvalidArgumentException('$object must be an instance of MergeableClassMetadata.');
62
        }
63
64 8
        $this->name = $object->name;
65 8
        $this->reflection = $object->reflection;
66 8
        $this->methodMetadata = array_merge($this->methodMetadata, $object->methodMetadata);
67 8
        $this->propertyMetadata = $this->mergePropertyMetadata($object);
68 8
        $this->fileResources = array_merge($this->fileResources, $object->fileResources);
69
70 8
        if ($object->createdAt < $this->createdAt) {
71
            $this->createdAt = $object->createdAt;
72
        }
73
74
        /** @var ClassMetadata $object */
75 8
        $this->restResource = $this->mergeField($this->restResource, $object->restResource);
76 8
        $this->idField = $this->mergeField($this->idField, $object->idField);
77 8
        $this->methods = $this->mergeField($this->methods, $object->methods);
78 8
        $this->namePrefix = $this->mergeField($this->namePrefix, $object->namePrefix);
79 8
        $this->pathPrefix = $this->mergeField($this->pathPrefix, $object->pathPrefix);
80 8
        $this->service = $this->mergeField($this->service, $object->service);
81 8
        $this->controller = $this->mergeField($this->controller, $object->controller);
82 8
    }
83
84
    /**
85
     * @param bool $restResource
86
     */
87 34
    public function setRestResource($restResource)
88
    {
89 34
        $this->restResource = $restResource;
90 34
    }
91
92
    /**
93
     * @return boolean
94
     */
95 26
    public function isRestResource()
96
    {
97 26
        return $this->restResource;
98
    }
99
100
    /**
101
     * @return string
102
     */
103 6
    public function getNamePrefix()
104
    {
105 6
        return $this->namePrefix;
106
    }
107
108
    /**
109
     * @param string $namePrefix
110
     */
111
    public function setNamePrefix($namePrefix)
112
    {
113
        $this->namePrefix = $namePrefix;
114
    }
115
116
    /**
117
     * @return string
118
     */
119 6
    public function getPathPrefix()
120
    {
121 6
        return $this->pathPrefix;
122
    }
123
124
    /**
125
     * @param string $pathPrefix
126
     */
127 24
    public function setPathPrefix(string $pathPrefix)
128
    {
129 24
        $this->pathPrefix = $pathPrefix;
130 24
    }
131
132
    /**
133
     * @return string
134
     */
135 6
    public function getController()
136
    {
137 6
        return $this->controller;
138
    }
139
140
    /**
141
     * @param string $controller
142
     */
143
    public function setController($controller)
144
    {
145
        $this->controller = $controller;
146
    }
147
148
    /**
149
     * @return string
150
     */
151 6
    public function getService()
152
    {
153 6
        return $this->service;
154
    }
155
156
    /**
157
     * @param string $service
158
     */
159
    public function setService($service)
160
    {
161
        $this->service = $service;
162
    }
163
164
    /**
165
     * @return Method[]
166
     */
167
    public function getMethods()
168
    {
169
        return $this->methods;
170
    }
171
172
    /**
173
     * @param string[] $methods
174
     */
175 34
    public function setMethods(array $methods)
176
    {
177 34
        $this->methods = $methods;
0 ignored issues
show
Documentation Bug introduced by
It seems like $methods of type array<integer,string> is incompatible with the declared type array<integer,object<Don...nnotation\Method>>|null of property $methods.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
178 34
    }
179
180 34
    public function getPropertyMetadata(string $property): ?PropertyMetadata
181
    {
182 34
        if (array_key_exists($property, $this->propertyMetadata)) {
183 34
            return $this->propertyMetadata[$property];
184
        }
185
186 30
        return null;
187
    }
188
189
    /**
190
     * @param MergeableInterface $object
191
     *
192
     * @return array
193
     */
194 8
    protected function mergePropertyMetadata(MergeableInterface $object): array
195
    {
196
        /** @var ClassMetadata $object */
197
        /** @var PropertyMetadata[] $mergedMetadata */
198 8
        $mergedMetadata = $this->propertyMetadata;
199
200 8
        foreach ($object->propertyMetadata as $otherMetadata) {
0 ignored issues
show
Bug introduced by
Accessing propertyMetadata on the interface Metadata\MergeableInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
201
            /** @var PropertyMetadata $otherMetadata */
202 8
            if (array_key_exists($otherMetadata->name, $mergedMetadata)) {
203 6
                $mergedMetadata[$otherMetadata->name] = $mergedMetadata[$otherMetadata->name]->merge($otherMetadata);
204
            } else {
205 8
                $mergedMetadata[$otherMetadata->name] = $otherMetadata;
206
            }
207
        }
208
209 8
        return $mergedMetadata;
210
    }
211
212 32
    public function getMethod(string $methodName): ?Method
213
    {
214 32
        if (null === $this->methods) {
215
            return null;
216
        }
217
218 32
        foreach ($this->methods as $method) {
219 32
            if ($methodName === $method->name) {
220 32
                return $method;
221
            }
222
        }
223
224 6
        return null;
225
    }
226
227 24
    public function hasMethod($methodName)
228
    {
229 24
        return null !== $this->getMethod($methodName);
230
    }
231
232 8
    private function mergeField($existing, $toMerge)
233
    {
234 8
        if (null !== $toMerge) {
235 8
            return $toMerge;
236
        }
237
238 8
        return $existing;
239
    }
240
241 2
    public function getIdField(string $default = 'id'): string
242
    {
243 2
        if (null !== $this->idField) {
244
            return $this->idField;
245
        }
246
247 2
        return $default;
248
    }
249
}
250