Passed
Push — master ( bcadde...416dc9 )
by Gabriel
02:50 queued 12s
created

Definition::hasItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
ccs 3
cts 3
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ByTIC\Models\SmartProperties\Properties\Definitions;
4
5
use ByTIC\Common\Records\Traits\HasSmartProperties\RecordsTrait;
0 ignored issues
show
Bug introduced by
The type ByTIC\Common\Records\Tra...Properties\RecordsTrait was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use ByTIC\Models\SmartProperties\Properties\AbstractProperty\Generic as Property;
7
use Exception;
8
use Nip\Records\RecordManager;
9
use RecursiveDirectoryIterator;
10
use RecursiveIteratorIterator;
11
12
/**
13
 * Class Definition
14
 * @package ByTIC\Models\SmartProperties\Properties\Definitions
15
 */
16
class Definition
17
{
18
    use Traits\HasItemsDirectoryTrait;
19
20
    /**
21
     * @var RecordManager|RecordsTrait
22
     */
23
    protected $manager;
24
25
    /**
26
     * @var string
27
     */
28
    protected $name = null;
29
30
    /**
31
     * @var string
32
     */
33
    protected $label = null;
34
35
    /**
36
     * @var string
37
     */
38
    protected $field;
39
40
    protected $items = null;
41
42
    protected $defaultValue = null;
43
44
    /**
45
     * @param $name
46
     *
47
     * @return Property
48
     * @throws Exception
49
     */
50 10
    public function getItem($name)
51
    {
52 10
        $items = $this->getItems();
53 10
        if (! $this->hasItem($name)) {
54
            throw new Exception(
55
                'Bad Item [' . $name . '] for smart property 
56
                [' . $this->getManager()->getController() . '::' . $this->getName() . ']
57
                [' . implode(',', array_keys($items)) . ']'
0 ignored issues
show
Bug introduced by
It seems like $items can also be of type null; however, parameter $input of array_keys() 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

57
                [' . implode(',', array_keys(/** @scrutinizer ignore-type */ $items)) . ']'
Loading history...
58
            );
59
        }
60
61 10
        return $items[$name];
62
    }
63
64
    /**
65
     * @return null|Property[]
66
     */
67 14
    public function getItems()
68
    {
69 14
        if ($this->items == null) {
70 14
            $this->initItems();
71
        }
72
73 14
        return $this->items;
74
    }
75
76 14
    public function initItems()
77
    {
78 14
        $names       = $this->getItemsNames();
79 14
        $this->items = [];
80 14
        foreach ($names as $name) {
81 14
            if (! $this->isAbstractItemName($name)) {
82 14
                $object                          = $this->newStatus($name);
83 14
                $this->items[$object->getName()] = $object;
84
            }
85
        }
86 14
    }
87
88
    /**
89
     * @return array
90
     */
91 15
    public function getItemsNames()
92
    {
93 15
        $names = $this->getItemsNamesFromManager();
94
95 15
        return $names ? $names : $this->getItemsNamesFromFiles();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $names ? $names :...etItemsNamesFromFiles() also could return the type true which is incompatible with the documented return type array.
Loading history...
96
    }
97
98
    /**
99
     * @return array|boolean
100
     */
101 15
    protected function getItemsNamesFromManager()
102
    {
103 15
        $methodName = 'get' . $this->getName() . 'Names';
104 15
        if (method_exists($this->getManager(), $methodName)) {
105
            return $this->getManager()->$methodName();
106
        }
107
108 15
        return false;
109
    }
110
111
    /**
112
     * @return mixed
113
     */
114 20
    public function getName()
115
    {
116 20
        if ($this->name === null) {
117 19
            $this->initName();
118
        }
119
120 20
        return $this->name;
121
    }
122
123
    /**
124
     * @param mixed $name
125
     */
126 20
    public function setName($name)
127
    {
128 20
        $this->name = $name;
129 20
    }
130
131 19
    protected function initName()
132
    {
133 19
        $name = inflector()->classify($this->getField());
134 19
        $this->setName($name);
135 19
    }
136
137
    /**
138
     * @return mixed
139
     */
140 19
    public function getField()
141
    {
142 19
        return $this->field;
143
    }
144
145
    /**
146
     * @param mixed $field
147
     */
148 18
    public function setField($field)
149
    {
150 18
        $this->field = $field;
151 18
    }
152
153
    /**
154
     * @return RecordManager
155
     */
156 17
    public function getManager()
157
    {
158 17
        return $this->manager;
159
    }
160
161
    /**
162
     * @param RecordManager|RecordsTrait $manager
163
     */
164 19
    public function setManager($manager)
165
    {
166 19
        $this->manager = $manager;
167 19
    }
168
169
    /**
170
     * @return array
171
     */
172 15
    protected function getItemsNamesFromFiles()
173
    {
174 15
        $directory = $this->getItemsDirectory();
175 15
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
176 15
        $names = [];
177 15
        foreach ($files as $file) {
178 15
            if ($file->isDir()) {
179 15
                continue;
180
            }
181 15
            $name = str_replace($directory, '', $file->getPathname());
182 15
            $name = str_replace('.php', '', $name);
183 15
            $names[] = trim($name, DIRECTORY_SEPARATOR . '\\');
184
        }
185
186 15
        return array_unique($names);
187
    }
188
189
190
    /**
191
     * @return string
192
     */
193 15
    public function getLabel()
194
    {
195 15
        if ($this->label === null) {
196 15
            $this->initLabel();
197
        }
198
199 15
        return $this->label;
200
    }
201
202
    /**
203
     * @param string $label
204
     */
205 15
    public function setLabel($label)
206
    {
207 15
        $this->label = $label;
208 15
    }
209
210 15
    protected function initLabel()
211
    {
212 15
        $name = inflector()->pluralize($this->getName());
213 15
        $this->setLabel($name);
214 15
    }
215
216
    /**
217
     * @param string $name
218
     *
219
     * @return bool
220
     */
221 14
    public function isAbstractItemName($name)
222
    {
223 14
        if (in_array($name, ['Abstract', 'Generic'])) {
224
            return true;
225
        }
226 14
        if (strpos($name, 'Abstract') === 0) {
227 14
            return true;
228
        }
229 14
        if (strpos($name, '\Abstract') !== false) {
230
            return true;
231
        }
232 14
        if (strpos($name, DIRECTORY_SEPARATOR . 'Abstract') !== false) {
233 3
            return true;
234
        }
235
236 14
        return false;
237
    }
238
239
    /**
240
     * @param string $type
241
     *
242
     * @return Property
243
     */
244 14
    public function newStatus($type = null)
245
    {
246 14
        $className = $this->getItemClass($type);
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type string; however, parameter $type of ByTIC\Models\SmartProper...inition::getItemClass() does only seem to accept null, 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

246
        $className = $this->getItemClass(/** @scrutinizer ignore-type */ $type);
Loading history...
247 14
        $object    = new $className();
248
        /** @var Property $object */
249 14
        $object->setManager($this->getManager());
250 14
        $object->setField($this->getField());
251
252 14
        return $object;
253
    }
254
255
    /**
256
     * @param null $type
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $type is correct as it would always require null to be passed?
Loading history...
257
     *
258
     * @return string
259
     */
260 14
    public function getItemClass($type = null)
261
    {
262 14
        $type = $type ? $type : $this->getDefaultValue();
0 ignored issues
show
introduced by
$type is of type null, thus it always evaluated to false.
Loading history...
263 14
        $type = str_replace(DIRECTORY_SEPARATOR, '\\', $type);
264
265 14
        return $this->getPropertyItemsRootNamespace() . inflector()->classify($type);
266
    }
267
268
    /**
269
     * @return string
270
     */
271 6
    public function getDefaultValue()
272
    {
273 6
        if ($this->defaultValue === null) {
274 6
            $this->initDefaultValue();
275
        }
276
277 6
        return $this->defaultValue;
278
    }
279
280
    /**
281
     * @param null $defaultValue
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $defaultValue is correct as it would always require null to be passed?
Loading history...
282
     */
283 6
    public function setDefaultValue($defaultValue)
284
    {
285 6
        $this->defaultValue = $defaultValue;
286 6
    }
287
288 6
    protected function initDefaultValue()
289
    {
290 6
        $managerDefaultValue = $this->getDefaultValueFromManager();
291 6
        if ($managerDefaultValue && $this->hasItem($managerDefaultValue)) {
292
            $defaultValue = $managerDefaultValue;
293
        } else {
294 6
            $keys         = array_keys($this->getItems());
0 ignored issues
show
Bug introduced by
It seems like $this->getItems() can also be of type null; however, parameter $input of array_keys() 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

294
            $keys         = array_keys(/** @scrutinizer ignore-type */ $this->getItems());
Loading history...
295 6
            $defaultValue = reset($keys);
296
        }
297 6
        $this->setDefaultValue($defaultValue);
0 ignored issues
show
Bug introduced by
It seems like $defaultValue can also be of type string and true; however, parameter $defaultValue of ByTIC\Models\SmartProper...tion::setDefaultValue() does only seem to accept null, 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

297
        $this->setDefaultValue(/** @scrutinizer ignore-type */ $defaultValue);
Loading history...
298 6
    }
299
300
    /**
301
     * @return bool|string
302
     */
303 6
    protected function getDefaultValueFromManager()
304
    {
305 6
        $method = 'getDefault' . $this->getName();
306 6
        if (method_exists($this->getManager(), $method)) {
307
            return $this->getManager()->{$method}();
308
        }
309
310 6
        return false;
311
    }
312
313
    /**
314
     * @param $name
315
     *
316
     * @return bool
317
     */
318 10
    public function hasItem($name)
319
    {
320 10
        $items = $this->getItems();
321
322 10
        return isset($items[$name]);
323
    }
324
325
    /**
326
     * @return string
327
     */
328 14
    protected function getPropertyItemsRootNamespace()
329
    {
330 14
        $manager = $this->getManager();
331 14
        $method = 'get' . $this->getName() . 'ItemsRootNamespace';
332 14
        if (method_exists($manager, $method)) {
333
            return $manager->{$method}();
334
        }
335
336 14
        $method = 'get' . $this->getName() . 'Namespace';
337 14
        if (method_exists($manager, $method)) {
338
            return $manager->{$method}();
339
        }
340
341 14
        return $manager->getModelNamespace() . $this->getLabel() . '\\';
342
    }
343
344
    /**
345
     * @param $name
346
     *
347
     * @return array
348
     */
349 2
    public function getValues($name)
350
    {
351 2
        $return = [];
352 2
        $items  = $this->getItems();
353
354 2
        foreach ($items as $type) {
355 2
            $method = 'get' . ucfirst($name);
356 2
            if (method_exists($type, $method)) {
357 2
                $return[] = $type->$method();
358
            } else {
359
                $return[] = $type->{$name};
360
            }
361
        }
362
363 2
        return $return;
364
    }
365
}
366