Passed
Push — master ( 9d7ef7...af08db )
by Andrea Marco
01:42 queued 11s
created

ManipulatesData::mutate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Cerbero\Dto\Traits;
4
5
use Cerbero\Dto\Manipulators\ArrayConverter;
6
7
use const Cerbero\Dto\MUTABLE;
0 ignored issues
show
Bug introduced by
The constant Cerbero\Dto\MUTABLE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
8
use const Cerbero\Dto\NONE;
0 ignored issues
show
Bug introduced by
The constant Cerbero\Dto\NONE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
9
use const Cerbero\Dto\PARTIAL;
0 ignored issues
show
Bug introduced by
The constant Cerbero\Dto\PARTIAL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
10
11
/**
12
 * Trait to manipulate a DTO data.
13
 *
14
 */
15
trait ManipulatesData
16
{
17
    /**
18
     * Merge the given data in the DTO
19
     *
20
     * @param iterable $data
21
     * @param int $flags
22
     * @return self
23
     */
24 9
    public function merge(iterable $data, int $flags = NONE): self
25
    {
26 9
        $replacements = ArrayConverter::instance()->convert($data);
27 9
        $mergedData = array_replace_recursive($this->toArray(), $replacements);
0 ignored issues
show
Bug introduced by
It seems like toArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

27
        $mergedData = array_replace_recursive($this->/** @scrutinizer ignore-call */ toArray(), $replacements);
Loading history...
Bug introduced by
It seems like $replacements can also be of type iterable; however, parameter $array1 of array_replace_recursive() 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

27
        $mergedData = array_replace_recursive($this->toArray(), /** @scrutinizer ignore-type */ $replacements);
Loading history...
28 9
        $mergedFlags = $this->mergeFlags($this->getFlags(), $flags);
0 ignored issues
show
Bug introduced by
The method mergeFlags() does not exist on Cerbero\Dto\Traits\ManipulatesData. Did you maybe mean merge()? ( Ignorable by Annotation )

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

28
        /** @scrutinizer ignore-call */ 
29
        $mergedFlags = $this->mergeFlags($this->getFlags(), $flags);

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...
Bug introduced by
It seems like getFlags() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

28
        $mergedFlags = $this->mergeFlags($this->/** @scrutinizer ignore-call */ getFlags(), $flags);
Loading history...
29
30 9
        if (!($this->getFlags() & MUTABLE)) {
31 6
            return new static($mergedData, $mergedFlags);
0 ignored issues
show
Unused Code introduced by
The call to Cerbero\Dto\Traits\ManipulatesData::__construct() has too many arguments starting with $mergedData. ( Ignorable by Annotation )

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

31
            return /** @scrutinizer ignore-call */ new static($mergedData, $mergedFlags);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
32
        }
33
34 3
        $this->flags = $mergedFlags;
0 ignored issues
show
Bug Best Practice introduced by
The property flags does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
35 3
        $this->propertiesMap = $this->mapData($mergedData);
0 ignored issues
show
Bug Best Practice introduced by
The property propertiesMap does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
It seems like mapData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

35
        /** @scrutinizer ignore-call */ 
36
        $this->propertiesMap = $this->mapData($mergedData);
Loading history...
36
37 3
        return $this;
38
    }
39
40
    /**
41
     * Retrieve the DTO including only the given properties
42
     *
43
     * @param array $properties
44
     * @param int $flags
45
     * @return self
46
     */
47 12
    public function only(array $properties, int $flags = NONE): self
48
    {
49 12
        $data = [];
50 12
        $isMutable = $this->getFlags() & MUTABLE;
51 12
        $mergedFlags = $this->mergeFlags($this->getFlagsWithoutDefaults(), $flags | PARTIAL);
0 ignored issues
show
Bug introduced by
It seems like getFlagsWithoutDefaults() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
        $mergedFlags = $this->mergeFlags($this->/** @scrutinizer ignore-call */ getFlagsWithoutDefaults(), $flags | PARTIAL);
Loading history...
52
53 12
        foreach ($this->getPropertiesMap() as $name => $property) {
0 ignored issues
show
Bug introduced by
It seems like getPropertiesMap() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

53
        foreach ($this->/** @scrutinizer ignore-call */ getPropertiesMap() as $name => $property) {
Loading history...
54 12
            if (in_array($name, $properties) && !$isMutable) {
55 6
                $data[$name] = $property->value();
56 12
            } elseif (!in_array($name, $properties) && $isMutable) {
57 10
                unset($this->propertiesMap[$name]);
58
            }
59
        }
60
61 12
        if ($isMutable) {
62 6
            $this->flags = $mergedFlags;
0 ignored issues
show
Bug Best Practice introduced by
The property flags does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
63 6
            return $this;
64
        }
65
66 6
        return new static($data, $mergedFlags);
0 ignored issues
show
Unused Code introduced by
The call to Cerbero\Dto\Traits\ManipulatesData::__construct() has too many arguments starting with $data. ( Ignorable by Annotation )

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

66
        return /** @scrutinizer ignore-call */ new static($data, $mergedFlags);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
67
    }
68
69
    /**
70
     * Retrieve the DTO excluding the given properties
71
     *
72
     * @param array $properties
73
     * @param int $flags
74
     * @return self
75
     */
76 6
    public function except(array $properties, int $flags = NONE): self
77
    {
78 6
        $propertiesToKeep = array_diff($this->getPropertyNames(), $properties);
0 ignored issues
show
Bug introduced by
It seems like getPropertyNames() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

78
        $propertiesToKeep = array_diff($this->/** @scrutinizer ignore-call */ getPropertyNames(), $properties);
Loading history...
79
80 6
        return $this->only($propertiesToKeep, $flags);
81
    }
82
83
    /**
84
     * Make the DTO mutable while calling the given callback
85
     *
86
     * @param callable $callback
87
     * @return self
88
     */
89 6
    public function mutate(callable $callback): self
90
    {
91 6
        $wasMutable = $this->getFlags() & MUTABLE;
92 6
        $this->flags |= MUTABLE;
93
94 6
        $callback($this);
95
96 6
        if (!$wasMutable) {
97 3
            $this->flags ^= MUTABLE;
98
        }
99
100 6
        return $this;
101
    }
102
}
103