Passed
Push — dev ( 40f0b5...3a2e98 )
by Fike
02:50
created

Operations   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 137
Duplicated Lines 10.22 %

Importance

Changes 0
Metric Value
wmc 42
dl 14
loc 137
c 0
b 0
f 0
rs 8.295

10 Methods

Rating   Name   Duplication   Size   Complexity  
A haveTypeConflict() 0 3 3
A conflict() 0 12 4
A from() 0 3 1
A haveConflicts() 0 9 3
A haveParameterConflicts() 0 8 4
B merge() 0 16 6
A havePropertyConflicts() 0 8 4
B toArray() 7 17 5
C fromArray() 0 22 7
B toStdObject() 7 17 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Operations often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Operations, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace AmaTeam\ElasticSearch\Mapping;
4
5
use AmaTeam\ElasticSearch\API\Mapping;
6
use AmaTeam\ElasticSearch\API\MappingInterface;
7
use stdClass;
8
9
class Operations
10
{
11
    const KEY_PROPERTIES = 'properties';
12
    const KEY_TYPE = 'type';
13
14
    public static function merge(MappingInterface ...$mappings): Mapping
15
    {
16
        $target = new Mapping();
17
        foreach ($mappings as $source) {
18
            if ($source->getType()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $source->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
19
                $target->setType($source->getType());
20
            }
21
            foreach ($source->getParameters() as $parameter => $value) {
22
                $target->setParameter($parameter, $value);
23
            }
24
            foreach ($source->getProperties() as $property => $mapping) {
25
                $candidate = $target->getProperty($property);
26
                $target->setProperty($property, $candidate ? static::merge($candidate, $mapping) : $mapping);
27
            }
28
        }
29
        return $target;
30
    }
31
32
    public static function from(MappingInterface $mapping): Mapping
33
    {
34
        return static::merge($mapping);
35
    }
36
    public static function conflict(MappingInterface ...$mappings): bool
37
    {
38
        $mappings = array_values($mappings);
39
        for ($i = 0; $i < sizeof($mappings) - 1; $i++) {
40
            $subject = $mappings[$i];
41
            for ($j = $i + 1; $j < sizeof($mappings); $j++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
42
                if (static::haveConflicts($subject, $mappings[$j])) {
43
                    return true;
44
                }
45
            }
46
        }
47
        return false;
48
    }
49
50
    private static function haveConflicts(MappingInterface $subject, MappingInterface $opponent): bool
51
    {
52
        if (static::haveTypeConflict($subject, $opponent)) {
53
            return true;
54
        }
55
        if (static::haveParameterConflicts($subject, $opponent)) {
56
            return true;
57
        }
58
        return static::havePropertyConflicts($subject, $opponent);
59
    }
60
61
    private static function haveTypeConflict(MappingInterface $subject, MappingInterface $opponent): bool
62
    {
63
        return $subject->getType() && $opponent->getType() && $subject->getType() !== $opponent->getType();
0 ignored issues
show
Bug Best Practice introduced by
The expression $opponent->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $subject->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
64
    }
65
66
    private static function haveParameterConflicts(MappingInterface $subject, MappingInterface $opponent): bool
67
    {
68
        foreach ($subject->getParameters() as $parameter => $value) {
69
            if ($opponent->hasParameter($parameter) && $opponent->getParameter($parameter) != $value) {
70
                return true;
71
            }
72
        }
73
        return false;
74
    }
75
76
    private static function havePropertyConflicts(MappingInterface $subject, MappingInterface $opponent): bool
77
    {
78
        foreach ($subject->getProperties() as $name => $property) {
79
            if ($opponent->hasProperty($name) && static::haveConflicts($property, $opponent->getProperty($name))) {
80
                return true;
81
            }
82
        }
83
        return false;
84
    }
85
86
    public static function toArray(MappingInterface $mapping): array
87
    {
88
        $target = [];
89
        foreach ($mapping->getParameters() as $parameter => $value) {
90
            $target[$parameter] = $value;
91
        }
92 View Code Duplication
        if (!empty($mapping->getProperties())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
            $properties = [];
94
            foreach ($mapping->getProperties() as $property => $mapping) {
95
                $properties[$property] = static::toArray($mapping);
96
            }
97
            $target[self::KEY_PROPERTIES] = $properties;
98
        }
99
        if ($mapping->getType()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mapping->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
100
            $target[self::KEY_TYPE] = $mapping->getType();
101
        }
102
        return $target;
103
    }
104
105
    public static function toStdObject(MappingInterface $mapping)
106
    {
107
        $target = new stdClass();
108
        foreach ($mapping->getParameters() as $parameter => $value) {
109
            $target->$parameter = $value;
110
        }
111 View Code Duplication
        if (!empty($mapping->getProperties())) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
            $properties = [];
113
            foreach ($mapping->getProperties() as $name => $property) {
114
                $properties[$name] = static::toStdObject($property);
115
            }
116
            $target->properties = $properties;
117
        }
118
        if ($mapping->getType()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $mapping->getType() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
119
            $target->type = $mapping->getType();
120
        }
121
        return $target;
122
    }
123
124
    public static function fromArray(array $source): Mapping
125
    {
126
        $target = new Mapping();
127
        if (isset($source[self::KEY_TYPE])) {
128
            $target->setType($source[self::KEY_TYPE]);
129
        }
130
        if (isset($source[self::KEY_PROPERTIES]) && is_array($source[self::KEY_PROPERTIES])) {
131
            $properties = [];
132
            foreach ($source[self::KEY_PROPERTIES] as $property => $mapping) {
133
                $properties[$property] = static::fromArray($mapping);
134
            }
135
            $target->setProperties($properties);
136
        }
137
        $parameters = [];
138
        foreach ($source as $parameter => $value) {
139
            if (in_array($parameter, [self::KEY_PROPERTIES, self::KEY_TYPE])) {
140
                continue;
141
            }
142
            $parameters[$parameter] = $value;
143
        }
144
        $target->setParameters($parameters);
145
        return $target;
146
    }
147
}
148