Passed
Push — master ( fc1289...318631 )
by Dominik
06:24
created

createCallback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Deserialization\Mapping;
6
7
use Chubbyphp\Deserialization\Accessor\PropertyAccessor;
8
use Chubbyphp\Deserialization\Denormalizer\CallbackFieldDenormalizer;
9
use Chubbyphp\Deserialization\Denormalizer\ConvertTypeFieldDenormalizer;
10
use Chubbyphp\Deserialization\Denormalizer\DateTimeFieldDenormalizer;
11
use Chubbyphp\Deserialization\Denormalizer\FieldDenormalizer;
12
use Chubbyphp\Deserialization\Denormalizer\FieldDenormalizerInterface;
13
use Chubbyphp\Deserialization\Denormalizer\Relation\EmbedManyFieldDenormalizer;
14
use Chubbyphp\Deserialization\Denormalizer\Relation\EmbedOneFieldDenormalizer;
15
use Chubbyphp\Deserialization\Denormalizer\Relation\ReferenceManyFieldDenormalizer;
16
use Chubbyphp\Deserialization\Denormalizer\Relation\ReferenceOneFieldDenormalizer;
17
18
final class DenormalizationFieldMappingBuilder implements DenormalizationFieldMappingBuilderInterface
19
{
20
    /**
21
     * @var string
22
     */
23
    private $name;
24
25
    /**
26
     * @var array
27
     */
28
    private $groups = [];
29
30
    /**
31
     * @var FieldDenormalizerInterface|null
32
     */
33
    private $fieldDenormalizer;
34
35 9
    private function __construct(string $name)
36
    {
37 9
        $this->name = $name;
38 9
    }
39
40
    /**
41
     * @param string $name
42
     *
43
     * @return DenormalizationFieldMappingBuilderInterface
44
     */
45 2
    public static function create(string $name): DenormalizationFieldMappingBuilderInterface
46
    {
47 2
        return new self($name);
48
    }
49
50
    /**
51
     * @param string   $name
52
     * @param callable $callback
53
     *
54
     * @return DenormalizationFieldMappingBuilderInterface
55
     */
56 1
    public static function createCallback(string $name, callable $callback): DenormalizationFieldMappingBuilderInterface
57
    {
58 1
        $self = new self($name);
59 1
        $self->fieldDenormalizer = new CallbackFieldDenormalizer($callback);
60
61 1
        return $self;
62
    }
63
64
    /**
65
     * @param string $name
66
     * @param string $type
67
     *
68
     * @return DenormalizationFieldMappingBuilderInterface
69
     */
70 1
    public static function createConvertType(string $name, string $type): DenormalizationFieldMappingBuilderInterface
71
    {
72 1
        $self = new self($name);
73 1
        $self->fieldDenormalizer = new ConvertTypeFieldDenormalizer(new PropertyAccessor($name), $type);
74
75 1
        return $self;
76
    }
77
78
    /**
79
     * @param string $name
80
     *
81
     * @return DenormalizationFieldMappingBuilderInterface
82
     */
83 1
    public static function createDateTime(string $name): DenormalizationFieldMappingBuilderInterface
84
    {
85 1
        $self = new self($name);
86 1
        $self->fieldDenormalizer = new DateTimeFieldDenormalizer(new PropertyAccessor($name));
87
88 1
        return $self;
89
    }
90
91
    /**
92
     * @param string $name
93
     * @param string $class
94
     *
95
     * @return DenormalizationFieldMappingBuilderInterface
96
     */
97 1 View Code Duplication
    public static function createEmbedMany(string $name, string $class): DenormalizationFieldMappingBuilderInterface
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...
98
    {
99 1
        $self = new self($name);
100 1
        $self->fieldDenormalizer = new EmbedManyFieldDenormalizer($class, new PropertyAccessor($name));
101
102 1
        return $self;
103
    }
104
105
    /**
106
     * @param string $name
107
     * @param string $class
108
     *
109
     * @return DenormalizationFieldMappingBuilderInterface
110
     */
111 1 View Code Duplication
    public static function createEmbedOne(string $name, string $class): DenormalizationFieldMappingBuilderInterface
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...
112
    {
113 1
        $self = new self($name);
114 1
        $self->fieldDenormalizer = new EmbedOneFieldDenormalizer($class, new PropertyAccessor($name));
115
116 1
        return $self;
117
    }
118
119
    /**
120
     * @param string   $name
121
     * @param callable $repository
122
     *
123
     * @return DenormalizationFieldMappingBuilderInterface
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
        callable $repository
128
    ): DenormalizationFieldMappingBuilderInterface {
129 1
        $self = new self($name);
130 1
        $self->fieldDenormalizer = new ReferenceManyFieldDenormalizer($repository, new PropertyAccessor($name));
131
132 1
        return $self;
133
    }
134
135
    /**
136
     * @param string   $name
137
     * @param callable $repository
138
     *
139
     * @return DenormalizationFieldMappingBuilderInterface
140
     */
141 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...
142
        string $name,
143
        callable $repository
144
    ): DenormalizationFieldMappingBuilderInterface {
145 1
        $self = new self($name);
146 1
        $self->fieldDenormalizer = new ReferenceOneFieldDenormalizer($repository, new PropertyAccessor($name));
147
148 1
        return $self;
149
    }
150
151
    /**
152
     * @param array $groups
153
     *
154
     * @return DenormalizationFieldMappingBuilderInterface
155
     */
156 1
    public function setGroups(array $groups): DenormalizationFieldMappingBuilderInterface
157
    {
158 1
        $this->groups = $groups;
159
160 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Chubbyphp\Deserializatio...tionFieldMappingBuilder) is incompatible with the return type declared by the interface Chubbyphp\Deserializatio...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...
161
    }
162
163
    /**
164
     * @param FieldDenormalizerInterface $fieldDenormalizer
165
     *
166
     * @return DenormalizationFieldMappingBuilderInterface
167
     */
168 1
    public function setFieldDenormalizer(
169
        FieldDenormalizerInterface $fieldDenormalizer
170
    ): DenormalizationFieldMappingBuilderInterface {
171 1
        $this->fieldDenormalizer = $fieldDenormalizer;
172
173 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this; (Chubbyphp\Deserializatio...tionFieldMappingBuilder) is incompatible with the return type declared by the interface Chubbyphp\Deserializatio...e::setFieldDenormalizer 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...
174
    }
175
176
    /**
177
     * @return DenormalizationFieldMappingInterface
178
     */
179 9
    public function getMapping(): DenormalizationFieldMappingInterface
180
    {
181 9
        return new DenormalizationFieldMapping(
182 9
            $this->name,
183 9
            $this->groups,
184 9
            $this->fieldDenormalizer ?? new FieldDenormalizer(new PropertyAccessor($this->name))
185
        );
186
    }
187
}
188