Passed
Push — master ( 3060b2...13f7cf )
by Dominik
02:58 queued 10s
created

NormalizationFieldMappingBuilder   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 197
Duplicated Lines 12.18 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 10
dl 24
loc 197
ccs 53
cts 53
cp 1
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A create() 0 9 1
A createCallback() 0 7 1
A createDateTime() 0 7 1
A createEmbedMany() 0 7 1
A createEmbedOne() 0 7 1
A createReferenceMany() 12 12 1
A createReferenceOne() 12 12 1
A setGroups() 0 6 1
A setFieldNormalizer() 0 12 1
A setPolicy() 0 6 1
A getMapping() 0 9 1

How to fix   Duplicated Code   

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:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Serialization\Mapping;
6
7
use Chubbyphp\Serialization\Accessor\PropertyAccessor;
8
use Chubbyphp\Serialization\Normalizer\CallbackFieldNormalizer;
9
use Chubbyphp\Serialization\Normalizer\DateTimeFieldNormalizer;
10
use Chubbyphp\Serialization\Normalizer\FieldNormalizer;
11
use Chubbyphp\Serialization\Normalizer\FieldNormalizerInterface;
12
use Chubbyphp\Serialization\Normalizer\Relation\EmbedManyFieldNormalizer;
13
use Chubbyphp\Serialization\Normalizer\Relation\EmbedOneFieldNormalizer;
14
use Chubbyphp\Serialization\Normalizer\Relation\ReferenceManyFieldNormalizer;
15
use Chubbyphp\Serialization\Normalizer\Relation\ReferenceOneFieldNormalizer;
16
use Chubbyphp\Serialization\Policy\NullPolicy;
17
use Chubbyphp\Serialization\Policy\PolicyInterface;
18
19
final class NormalizationFieldMappingBuilder implements NormalizationFieldMappingBuilderInterface
20
{
21
    /**
22
     * @var string
23
     */
24
    private $name;
25
26
    /**
27
     * @var array
28
     */
29
    private $groups = [];
30
31
    /**
32
     * @var FieldNormalizerInterface|null
33
     */
34
    private $fieldNormalizer;
35
36
    /**
37
     * @var PolicyInterface|null
38
     */
39
    private $policy;
40
41
    /**
42
     * @param string $name
43
     */
44 10
    private function __construct(string $name)
45
    {
46 10
        $this->name = $name;
47 10
    }
48
49
    /**
50
     * @param string $name
51
     * @param FieldNormalizerInterface|null $fieldNormalizer
52
     *
53
     * @return NormalizationFieldMappingBuilderInterface
54
     */
55 3
    public static function create(
56
        string $name,
57
        FieldNormalizerInterface $fieldNormalizer = null
58
    ): NormalizationFieldMappingBuilderInterface {
59 3
        $self = new self($name);
60 3
        $self->fieldNormalizer = $fieldNormalizer;
61
62 3
        return $self;
63
    }
64
65
    /**
66
     * @param string   $name
67
     * @param callable $callback
68
     *
69
     * @return NormalizationFieldMappingBuilderInterface
70
     */
71 1
    public static function createCallback(string $name, callable $callback): NormalizationFieldMappingBuilderInterface
72
    {
73 1
        $self = new self($name);
74 1
        $self->fieldNormalizer = new CallbackFieldNormalizer($callback);
75
76 1
        return $self;
77
    }
78
79
    /**
80
     * @param string $name
81
     * @param string $format
82
     *
83
     * @return NormalizationFieldMappingBuilderInterface
84
     */
85 2
    public static function createDateTime(string $name, string $format = 'c'): NormalizationFieldMappingBuilderInterface
86
    {
87 2
        $self = new self($name);
88 2
        $self->fieldNormalizer = new DateTimeFieldNormalizer(new PropertyAccessor($name), $format);
89
90 2
        return $self;
91
    }
92
93
    /**
94
     * @param string $name
95
     *
96
     * @return NormalizationFieldMappingBuilderInterface
97
     */
98 1
    public static function createEmbedMany(string $name): NormalizationFieldMappingBuilderInterface
99
    {
100 1
        $self = new self($name);
101 1
        $self->fieldNormalizer = new EmbedManyFieldNormalizer(new PropertyAccessor($name));
102
103 1
        return $self;
104
    }
105
106
    /**
107
     * @param string $name
108
     *
109
     * @return NormalizationFieldMappingBuilderInterface
110
     */
111 1
    public static function createEmbedOne(string $name): NormalizationFieldMappingBuilderInterface
112
    {
113 1
        $self = new self($name);
114 1
        $self->fieldNormalizer = new EmbedOneFieldNormalizer(new PropertyAccessor($name));
115
116 1
        return $self;
117
    }
118
119
    /**
120
     * @param string $name
121
     * @param string $idName
122
     *
123
     * @return NormalizationFieldMappingBuilderInterface
124
     */
125 1 View Code Duplication
    public static function createReferenceMany(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
126
        string $name,
127
        string $idName = 'id'
128
    ): NormalizationFieldMappingBuilderInterface {
129 1
        $self = new self($name);
130 1
        $self->fieldNormalizer = new ReferenceManyFieldNormalizer(
131 1
            new PropertyAccessor($idName),
132 1
            new PropertyAccessor($name)
133
        );
134
135 1
        return $self;
136
    }
137
138
    /**
139
     * @param string $name
140
     * @param string $idName
141
     *
142
     * @return NormalizationFieldMappingBuilderInterface
143
     */
144 1 View Code Duplication
    public static function createReferenceOne(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
145
        string $name,
146
        string $idName = 'id'
147
    ): NormalizationFieldMappingBuilderInterface {
148 1
        $self = new self($name);
149 1
        $self->fieldNormalizer = new ReferenceOneFieldNormalizer(
150 1
            new PropertyAccessor($idName),
151 1
            new PropertyAccessor($name)
152
        );
153
154 1
        return $self;
155
    }
156
157
    /**
158
     * @deprecated
159
     *
160
     * @param array $groups
161
     *
162
     * @return NormalizationFieldMappingBuilderInterface
163
     */
164 1
    public function setGroups(array $groups): NormalizationFieldMappingBuilderInterface
165
    {
166 1
        $this->groups = $groups;
167
168 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Chubbyphp\Serialization\...tionFieldMappingBuilder) is incompatible with the return type declared by the interface Chubbyphp\Serialization\...derInterface::setGroups of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
169
    }
170
171
    /**
172
     * @deprecated
173
     *
174
     * @param FieldNormalizerInterface $fieldNormalizer
175
     *
176
     * @return NormalizationFieldMappingBuilderInterface
177
     */
178 1
    public function setFieldNormalizer(
179
        FieldNormalizerInterface $fieldNormalizer
180
    ): NormalizationFieldMappingBuilderInterface {
181 1
        @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
182 1
            'Utilize second parameter of create method instead',
183 1
            E_USER_DEPRECATED
184
        );
185
186 1
        $this->fieldNormalizer = $fieldNormalizer;
187
188 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Chubbyphp\Serialization\...tionFieldMappingBuilder) is incompatible with the return type declared by the interface Chubbyphp\Serialization\...ace::setFieldNormalizer of type self.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
189
    }
190
191
    /**
192
     * @param PolicyInterface $policy
193
     *
194
     * @return NormalizationFieldMappingBuilderInterface
195
     */
196 1
    public function setPolicy(PolicyInterface $policy): NormalizationFieldMappingBuilderInterface
197
    {
198 1
        $this->policy = $policy;
199
200 1
        return $this;
201
    }
202
203
    /**
204
     * @return NormalizationFieldMappingInterface
205
     */
206 10
    public function getMapping(): NormalizationFieldMappingInterface
207
    {
208 10
        return new NormalizationFieldMapping(
209 10
            $this->name,
210 10
            $this->groups,
211 10
            $this->fieldNormalizer ?? new FieldNormalizer(new PropertyAccessor($this->name)),
212 10
            $this->policy ?? new NullPolicy()
213
        );
214
    }
215
}
216