Passed
Pull Request — master (#7)
by
unknown
02:29
created

Service   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 252
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 252
rs 8.3999
c 0
b 0
f 0
wmc 38

12 Methods

Rating   Name   Duplication   Size   Complexity  
A setDependsOn() 0 4 1
A parsePayload() 0 16 2
A setServiceName() 0 4 1
C checkValidity() 0 55 22
A setPorts() 0 4 1
A setEnvironments() 0 4 1
A setInternalPorts() 0 4 1
A __construct() 0 10 1
A setImage() 0 4 1
B serializeToDockerComposeService() 0 40 5
A setLabels() 0 4 1
A setVolumes() 0 4 1
1
<?php
2
3
namespace TheAentMachine\AentDockerCompose\Service;
4
5
use TheAentMachine\AentDockerCompose\Service\Enum\VolumeTypeEnum;
6
use TheAentMachine\AentDockerCompose\Service\Exception\EmptyAttributeException;
7
use TheAentMachine\AentDockerCompose\Service\Exception\KeysMissingInArrayException;
8
use TheAentMachine\AentDockerCompose\Service\Exception\VolumeTypeException;
9
10
class Service
11
{
12
13
    /** @var string */
14
    protected $serviceName;
15
    /** @var string */
16
    protected $image;
17
    /** @var array */
18
    protected $internalPorts;
19
    /** @var array */
20
    protected $dependsOn;
21
    /** @var array */
22
    protected $ports;
23
    /** @var array */
24
    protected $labels;
25
    /** @var array */
26
    protected $environments;
27
    /** @var array */
28
    protected $volumes;
29
30
    /**
31
     * Service constructor.
32
     */
33
    public function __construct()
34
    {
35
        $this->serviceName = '';
36
        $this->image = '';
37
        $this->internalPorts = array();
38
        $this->dependsOn = array();
39
        $this->ports = array();
40
        $this->labels = array();
41
        $this->environments = array();
42
        $this->volumes = array();
43
    }
44
45
46
    /**
47
     * @param string $serviceName
48
     * @return Service
49
     */
50
    public function setServiceName(string $serviceName): Service
51
    {
52
        $this->serviceName = $serviceName;
53
        return $this;
54
    }
55
56
    /**
57
     * @param string $image
58
     * @return Service
59
     */
60
    public function setImage(string $image): Service
61
    {
62
        $this->image = $image;
63
        return $this;
64
    }
65
66
    /**
67
     * @param int[]|string[] $internalPorts
68
     * @return Service
69
     */
70
    public function setInternalPorts(array $internalPorts): Service
71
    {
72
        $this->internalPorts = $internalPorts;
73
        return $this;
74
    }
75
76
    /**
77
     * @param string[] $dependsOn
78
     * @return Service
79
     */
80
    public function setDependsOn(array $dependsOn): Service
81
    {
82
        $this->dependsOn = $dependsOn;
83
        return $this;
84
    }
85
86
    /**
87
     * @param string[] $ports
88
     * @return Service
89
     */
90
    public function setPorts(array $ports): Service
91
    {
92
        $this->ports = $ports;
93
        return $this;
94
    }
95
96
    /**
97
     * @param string[] $labels
98
     * @return Service
99
     */
100
    public function setLabels(array $labels): Service
101
    {
102
        $this->labels = $labels;
103
        return $this;
104
    }
105
106
    /**
107
     * @param string[] $environments
108
     * @return Service
109
     */
110
    public function setEnvironments(array $environments): Service
111
    {
112
        $this->environments = $environments;
113
        return $this;
114
    }
115
116
    /**
117
     * @param string[] $volumes
118
     * @return Service
119
     */
120
    public function setVolumes(array $volumes): Service
121
    {
122
        $this->volumes = $volumes;
123
        return $this;
124
    }
125
126
    /**
127
     * @param mixed[] $payload
128
     * @return Service
129
     * @throws EmptyAttributeException
130
     * @throws KeysMissingInArrayException
131
     * @throws VolumeTypeException
132
     */
133
    public static function parsePayload(array $payload): Service
134
    {
135
        $service = new Service();
136
        $service->serviceName = $payload['serviceName'] ?? '';
137
        $s = $payload['service'] ?? array();
138
        if (!empty($s)) {
139
            $service->image = $s['image'] ?? '';
140
            $service->internalPorts = $s['internalPorts'] ?? '';
0 ignored issues
show
Documentation Bug introduced by
It seems like $s['internalPorts'] ?? '' can also be of type string. However, the property $internalPorts is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
141
            $service->dependsOn = $s['dependsOn'] ?? array();
142
            $service->ports = $s['ports'] ?? array();
143
            $service->labels = $s['labels'] ?? array();
144
            $service->environments = $s['environments'] ?? array();
145
            $service->volumes = $s['volumes'] ?? array();
146
        }
147
        $service->checkValidity(true);
148
        return $service;
149
    }
150
151
    /**
152
     * @param bool $throwException
153
     * @return bool
154
     * @throws EmptyAttributeException
155
     * @throws KeysMissingInArrayException
156
     * @throws VolumeTypeException
157
     */
158
    public function checkValidity(bool $throwException = false): bool
159
    {
160
        if (empty($this->serviceName)) {
161
            if ($throwException) {
162
                throw new EmptyAttributeException('serviceName');
163
            }
164
            return false;
165
        }
166
167
        $wantedKeys = array('source', 'target');
168
        foreach ($this->ports as $arr) {
169
            if (!array_key_exists('source', $arr) || !array_key_exists('target', $arr)) {
170
                if ($throwException) {
171
                    throw new KeysMissingInArrayException($arr, $wantedKeys);
172
                }
173
                return false;
174
            }
175
        }
176
177
        $wantedKeys = array('key', 'value');
178
        foreach ($this->labels as $label) {
179
            if (!array_key_exists('key', $label) || !array_key_exists('value', $label)) {
180
                if ($throwException) {
181
                    throw new KeysMissingInArrayException($label, $wantedKeys);
182
                }
183
                return false;
184
            }
185
        }
186
        foreach ($this->environments as $environment) {
187
            if (!array_key_exists('key', $environment) || !array_key_exists('value', $environment)) {
188
                if ($throwException) {
189
                    throw new KeysMissingInArrayException($environment, $wantedKeys);
190
                }
191
                return false;
192
            }
193
        }
194
195
        $wantedKeys = array('type', 'source', 'target');
196
        $wantedTypes = VolumeTypeEnum::getVolumeTypes();
197
        foreach ($this->volumes as $v) {
198
            if (!array_key_exists('type', $v) || !array_key_exists('source', $v) || !array_key_exists('target', $v)) {
199
                if ($throwException) {
200
                    throw new KeysMissingInArrayException($v, $wantedKeys);
201
                }
202
                return false;
203
            }
204
            if (!\in_array($v['type'], $wantedTypes, true)) {
205
                if ($throwException) {
206
                    throw new VolumeTypeException($v['type']);
207
                }
208
                return false;
209
            }
210
        }
211
212
        return true;
213
    }
214
215
    /**
216
     * @param bool $checkValidity
217
     * @return mixed[]
218
     * @throws EmptyAttributeException
219
     * @throws KeysMissingInArrayException
220
     * @throws VolumeTypeException
221
     */
222
    public function serializeToDockerComposeService(bool $checkValidity = false): array
223
    {
224
        if ($checkValidity) {
225
            $this->checkValidity(true);
226
        }
227
228
        $portMap = function ($port) {
229
            return $port['source'] . ':' . $port['target'];
230
        };
231
232
        $keyValueMap = function ($item) {
233
            return $item['key'] . '=' . $item['value'];
234
        };
235
236
        $dockerService = array(
237
            'services' => Utils::arrayFilterRec(array(
238
                $this->serviceName => [
239
                    'image' => $this->image,
240
                    'depends_on' => $this->dependsOn,
241
                    'ports' => array_map($portMap, $this->ports),
242
                    'labels' => array_map($keyValueMap, $this->labels),
243
                    'environments' => array_map($keyValueMap, $this->environments),
244
                    'volumes' => $this->volumes,
245
                ],
246
            )),
247
        );
248
249
        $namedVolumes = array();
250
        foreach ($this->volumes as $volume) {
251
            // case it's a named volume
252
            if ($volume['type'] === VolumeTypeEnum::VOLUME) {
253
                // for now we just add them without any option
254
                $namedVolumes[$volume['source']] = null;
255
            }
256
        }
257
258
        if (!empty($namedVolumes)) {
259
            $dockerService['volumes'] = $namedVolumes;
260
        }
261
        return $dockerService;
262
    }
263
}
264