1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace TheAentMachine\Service; |
4
|
|
|
|
5
|
|
|
use JsonSerializable; |
6
|
|
|
use Opis\JsonSchema\ValidationError; |
7
|
|
|
use Opis\JsonSchema\Validator; |
8
|
|
|
use TheAentMachine\Aenthill\Manifest; |
9
|
|
|
use TheAentMachine\Aenthill\CommonMetadata; |
10
|
|
|
use TheAentMachine\Service\Enum\EnvVariableTypeEnum; |
11
|
|
|
use TheAentMachine\Service\Enum\VolumeTypeEnum; |
12
|
|
|
use TheAentMachine\Service\Environment\EnvVariable; |
13
|
|
|
use TheAentMachine\Service\Exception\ServiceException; |
14
|
|
|
use TheAentMachine\Service\Volume\BindVolume; |
15
|
|
|
use TheAentMachine\Service\Volume\NamedVolume; |
16
|
|
|
use TheAentMachine\Service\Volume\TmpfsVolume; |
17
|
|
|
use TheAentMachine\Service\Volume\Volume; |
18
|
|
|
|
19
|
|
|
class Service implements JsonSerializable |
20
|
|
|
{ |
21
|
|
|
/** @var string */ |
22
|
|
|
private $serviceName = ''; |
23
|
|
|
/** @var string|null */ |
24
|
|
|
private $image; |
25
|
|
|
/** @var string[] */ |
26
|
|
|
private $command = []; |
27
|
|
|
/** @var int[] */ |
28
|
|
|
private $internalPorts = []; |
29
|
|
|
/** @var string[] */ |
30
|
|
|
private $dependsOn = []; |
31
|
|
|
/** @var mixed[] */ |
32
|
|
|
private $ports = []; |
33
|
|
|
/** @var mixed[] */ |
34
|
|
|
private $labels = []; |
35
|
|
|
/** @var mixed[] */ |
36
|
|
|
private $environment = []; |
37
|
|
|
/** @var mixed[] */ |
38
|
|
|
private $volumes = []; |
39
|
|
|
/** @var null|bool */ |
40
|
|
|
private $needVirtualHost; |
41
|
|
|
/** @var null|bool */ |
42
|
|
|
private $needBuild; |
43
|
|
|
/** @var \stdClass */ |
44
|
|
|
private $validatorSchema; |
45
|
|
|
/** @var string[] */ |
46
|
|
|
private $dockerfileCommands = []; |
47
|
|
|
/** @var string */ |
48
|
|
|
private $requestMemory = ''; |
49
|
|
|
/** @var string */ |
50
|
|
|
private $requestCpu = ''; |
51
|
|
|
/** @var string */ |
52
|
|
|
private $limitMemory = ''; |
53
|
|
|
/** @var string */ |
54
|
|
|
private $limitCpu = ''; |
55
|
|
|
|
56
|
|
|
/** @var string[] */ |
57
|
|
|
private $destEnvTypes = []; // empty === all env types |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Service constructor. |
61
|
|
|
*/ |
62
|
|
|
public function __construct() |
63
|
|
|
{ |
64
|
|
|
$this->validatorSchema = \GuzzleHttp\json_decode((string)file_get_contents(__DIR__ . '/ServiceJsonSchema.json'), false); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @param mixed[] $payload |
69
|
|
|
* @return Service |
70
|
|
|
* @throws ServiceException |
71
|
|
|
*/ |
72
|
|
|
public static function parsePayload(array $payload): Service |
73
|
|
|
{ |
74
|
|
|
$service = new self(); |
75
|
|
|
$service->checkValidity($payload); |
76
|
|
|
$service->serviceName = $payload['serviceName'] ?? ''; |
77
|
|
|
$s = $payload['service'] ?? []; |
78
|
|
|
if (!empty($s)) { |
79
|
|
|
$service->image = $s['image'] ?? null; |
80
|
|
|
$service->command = $s['command'] ?? []; |
81
|
|
|
$service->internalPorts = $s['internalPorts'] ?? []; |
82
|
|
|
$service->dependsOn = $s['dependsOn'] ?? []; |
83
|
|
|
$service->ports = $s['ports'] ?? []; |
84
|
|
|
$service->labels = $s['labels'] ?? []; |
85
|
|
|
if (!empty($s['environment'])) { |
86
|
|
|
foreach ($s['environment'] as $key => $env) { |
87
|
|
|
$service->addEnvVar($key, $env['value'], $env['type']); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
if (!empty($s['volumes'])) { |
91
|
|
|
foreach ($s['volumes'] as $vol) { |
92
|
|
|
$service->addVolume($vol['type'], $vol['source'], $vol['target'] ?? '', $vol['readOnly'] ?? false); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
$service->needVirtualHost = $s['needVirtualHost'] ?? null; |
96
|
|
|
$service->needBuild = $s['needBuild'] ?? null; |
97
|
|
|
} |
98
|
|
|
$service->dockerfileCommands = $payload['dockerfileCommands'] ?? []; |
99
|
|
|
$service->destEnvTypes = $payload['destEnvTypes'] ?? []; |
100
|
|
|
$service->dockerfileCommands = $payload['dockerfileCommands'] ?? ''; |
|
|
|
|
101
|
|
|
|
102
|
|
|
$service->requestMemory = $payload['requestMemory'] ?? ''; |
103
|
|
|
$service->requestCpu = $payload['requestCpu'] ?? ''; |
104
|
|
|
$service->limitMemory = $payload['limitMemory'] ?? ''; |
105
|
|
|
$service->limitCpu = $payload['limitCpu'] ?? ''; |
106
|
|
|
return $service; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Specify data which should be serialized to JSON |
111
|
|
|
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php |
112
|
|
|
* @return array data which can be serialized by <b>json_encode</b>, |
113
|
|
|
* which is a value of any type other than a resource. |
114
|
|
|
* @since 5.4.0 |
115
|
|
|
* @throws ServiceException |
116
|
|
|
*/ |
117
|
|
|
public function jsonSerialize(): array |
118
|
|
|
{ |
119
|
|
|
$jsonSerializeMap = function (JsonSerializable $obj): array { |
120
|
|
|
return $obj->jsonSerialize(); |
121
|
|
|
}; |
122
|
|
|
|
123
|
|
|
$json = array( |
124
|
|
|
'serviceName' => $this->serviceName, |
125
|
|
|
); |
126
|
|
|
|
127
|
|
|
$service = array_filter([ |
128
|
|
|
'image' => $this->image, |
129
|
|
|
'command' => $this->command, |
130
|
|
|
'internalPorts' => $this->internalPorts, |
131
|
|
|
'dependsOn' => $this->dependsOn, |
132
|
|
|
'ports' => $this->ports, |
133
|
|
|
'labels' => $this->labels, |
134
|
|
|
'environment' => array_map($jsonSerializeMap, $this->environment), |
135
|
|
|
'volumes' => array_map($jsonSerializeMap, $this->volumes), |
136
|
|
|
'needVirtualHost' => $this->needVirtualHost, |
137
|
|
|
'needBuild' => $this->needBuild, |
138
|
|
|
]); |
139
|
|
|
|
140
|
|
|
if (!empty($service)) { |
141
|
|
|
$json['service'] = $service; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
if (!empty($this->dockerfileCommands)) { |
145
|
|
|
$json['dockerfileCommands'] = $this->dockerfileCommands; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
$json['destEnvTypes'] = $this->destEnvTypes; |
149
|
|
|
|
150
|
|
|
$resources = array_filter([ |
151
|
|
|
'requestMemory' => $this->requestMemory, |
152
|
|
|
'requestCpu' => $this->requestCpu, |
153
|
|
|
'limitMemory' => $this->limitMemory, |
154
|
|
|
'limitCpu' => $this->limitCpu |
155
|
|
|
]); |
156
|
|
|
|
157
|
|
|
if (!empty($resources)) { |
158
|
|
|
$json = array_merge($json, $resources); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
$this->checkValidity($json); |
162
|
|
|
return $json; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** @return mixed[] */ |
166
|
|
|
public function imageJsonSerialize(): array |
167
|
|
|
{ |
168
|
|
|
$dockerfileCommands = []; |
169
|
|
|
$dockerfileCommands[] = 'FROM ' . $this->image; |
170
|
|
|
foreach ($this->environment as $key => $env) { |
171
|
|
|
if ($env->getType() === EnvVariableTypeEnum::IMAGE_ENV_VARIABLE) { |
172
|
|
|
$dockerfileCommands[] = "ENV $key" . '=' . $env->getValue(); |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
foreach ($this->volumes as $volume) { |
176
|
|
|
if ($volume->getType() === VolumeTypeEnum::BIND_VOLUME) { |
177
|
|
|
$dockerfileCommands[] = 'COPY ' . $volume->getSource() . ' ' . $volume->getTarget(); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
if (!empty($this->command)) { |
182
|
|
|
$dockerfileCommands[] = 'CMD ' . implode(' ', $this->command); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
$dockerfileCommands = array_merge($dockerfileCommands, $this->dockerfileCommands); |
186
|
|
|
|
187
|
|
|
return [ |
188
|
|
|
'serviceName' => $this->serviceName, |
189
|
|
|
'dockerfileCommands' => $dockerfileCommands, |
190
|
|
|
'destEnvTypes' => $this->destEnvTypes, |
191
|
|
|
]; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @param \stdClass|array|string $data |
196
|
|
|
* @return bool |
197
|
|
|
* @throws ServiceException |
198
|
|
|
*/ |
199
|
|
|
private function checkValidity($data): bool |
200
|
|
|
{ |
201
|
|
|
if (\is_array($data)) { |
202
|
|
|
$data = \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($data), false); |
203
|
|
|
} |
204
|
|
|
$validator = new Validator(); |
205
|
|
|
$result = $validator->dataValidation($data, $this->validatorSchema); |
206
|
|
|
if (!$result->isValid()) { |
207
|
|
|
/** @var ValidationError $vError */ |
208
|
|
|
$vError = $result->getFirstError(); |
209
|
|
|
throw ServiceException::invalidServiceData($vError); |
210
|
|
|
} |
211
|
|
|
return $result->isValid(); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
|
215
|
|
|
/************************ getters **********************/ |
216
|
|
|
|
217
|
|
|
public function getServiceName(): string |
218
|
|
|
{ |
219
|
|
|
return $this->serviceName; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
public function getImage(): ?string |
223
|
|
|
{ |
224
|
|
|
return $this->image; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** @return string[] */ |
228
|
|
|
public function getCommand(): array |
229
|
|
|
{ |
230
|
|
|
return $this->command; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** @return int[] */ |
234
|
|
|
public function getInternalPorts(): array |
235
|
|
|
{ |
236
|
|
|
return $this->internalPorts; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** @return string[] */ |
240
|
|
|
public function getDependsOn(): array |
241
|
|
|
{ |
242
|
|
|
return $this->dependsOn; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** @return mixed[] */ |
246
|
|
|
public function getPorts(): array |
247
|
|
|
{ |
248
|
|
|
return $this->ports; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** @return mixed[] */ |
252
|
|
|
public function getLabels(): array |
253
|
|
|
{ |
254
|
|
|
return $this->labels; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** @return mixed[] */ |
258
|
|
|
public function getEnvironment(): array |
259
|
|
|
{ |
260
|
|
|
return $this->environment; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** @return mixed[] */ |
264
|
|
|
public function getVolumes(): array |
265
|
|
|
{ |
266
|
|
|
return $this->volumes; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
public function getNeedVirtualHost(): ?bool |
270
|
|
|
{ |
271
|
|
|
return $this->needVirtualHost; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
public function getNeedBuild(): ?bool |
275
|
|
|
{ |
276
|
|
|
return $this->needBuild; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** @return string[] */ |
280
|
|
|
public function getDockerfileCommands(): array |
281
|
|
|
{ |
282
|
|
|
return $this->dockerfileCommands; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
public function getRequestMemory(): string |
286
|
|
|
{ |
287
|
|
|
return $this->requestMemory; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
public function getRequestCpu(): string |
291
|
|
|
{ |
292
|
|
|
return $this->requestCpu; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
public function getLimitMemory(): string |
296
|
|
|
{ |
297
|
|
|
return $this->limitMemory; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
public function getLimitCpu(): string |
301
|
|
|
{ |
302
|
|
|
return $this->limitCpu; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** @return string[] */ |
306
|
|
|
public function getDestEnvTypes(): array |
307
|
|
|
{ |
308
|
|
|
return $this->destEnvTypes; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
|
312
|
|
|
/************************ setters **********************/ |
313
|
|
|
|
314
|
|
|
public function setServiceName(string $serviceName): void |
315
|
|
|
{ |
316
|
|
|
$this->serviceName = $serviceName; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
public function setImage(?string $image): void |
320
|
|
|
{ |
321
|
|
|
$this->image = $image; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
/** @param string[] $command */ |
325
|
|
|
public function setCommand(array $command): void |
326
|
|
|
{ |
327
|
|
|
$this->command = $command; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** @param int[] $internalPorts */ |
331
|
|
|
public function setInternalPorts(array $internalPorts): void |
332
|
|
|
{ |
333
|
|
|
$this->internalPorts = $internalPorts; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** @param string[] $dependsOn */ |
337
|
|
|
public function setDependsOn(array $dependsOn): void |
338
|
|
|
{ |
339
|
|
|
$this->dependsOn = $dependsOn; |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
public function setRequestMemory(string $requestMemory): void |
343
|
|
|
{ |
344
|
|
|
$this->requestMemory = $requestMemory; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
public function setRequestCpu(string $requestCpu): void |
348
|
|
|
{ |
349
|
|
|
$this->requestCpu = $requestCpu; |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
public function setLimitMemory(string $limitMemory): void |
353
|
|
|
{ |
354
|
|
|
$this->limitMemory = $limitMemory; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
public function setLimitCpu(string $limitCpu): void |
358
|
|
|
{ |
359
|
|
|
$this->limitCpu = $limitCpu; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
public function setNeedVirtualHost(?bool $needVirtualHost): void |
363
|
|
|
{ |
364
|
|
|
$this->needVirtualHost = $needVirtualHost; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
public function setNeedBuild(?bool $needBuild): void |
368
|
|
|
{ |
369
|
|
|
$this->needBuild = $needBuild; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
|
373
|
|
|
/************************ adders **********************/ |
374
|
|
|
|
375
|
|
|
public function addCommand(string $command): void |
376
|
|
|
{ |
377
|
|
|
$this->command[] = $command; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
public function addInternalPort(int $internalPort): void |
381
|
|
|
{ |
382
|
|
|
$this->internalPorts[] = $internalPort; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
public function addDependsOn(string $dependsOn): void |
386
|
|
|
{ |
387
|
|
|
$this->dependsOn[] = $dependsOn; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
public function addPort(int $source, int $target): void |
391
|
|
|
{ |
392
|
|
|
$this->ports[] = array( |
393
|
|
|
'source' => $source, |
394
|
|
|
'target' => $target, |
395
|
|
|
); |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
public function addLabel(string $key, string $value): void |
399
|
|
|
{ |
400
|
|
|
$this->labels[$key] = array( |
401
|
|
|
'value' => $value, |
402
|
|
|
); |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
|
406
|
|
|
/************************ environment adders **********************/ |
407
|
|
|
|
408
|
|
|
/** @throws ServiceException */ |
409
|
|
|
private function addEnvVar(string $key, string $value, string $type): void |
410
|
|
|
{ |
411
|
|
|
switch ($type) { |
412
|
|
|
case EnvVariableTypeEnum::SHARED_ENV_VARIABLE: |
413
|
|
|
$this->addSharedEnvVariable($key, $value); |
414
|
|
|
break; |
415
|
|
|
case EnvVariableTypeEnum::SHARED_SECRET: |
416
|
|
|
$this->addSharedSecret($key, $value); |
417
|
|
|
break; |
418
|
|
|
case EnvVariableTypeEnum::IMAGE_ENV_VARIABLE: |
419
|
|
|
$this->addImageEnvVariable($key, $value); |
420
|
|
|
break; |
421
|
|
|
case EnvVariableTypeEnum::CONTAINER_ENV_VARIABLE: |
422
|
|
|
$this->addContainerEnvVariable($key, $value); |
423
|
|
|
break; |
424
|
|
|
default: |
425
|
|
|
throw ServiceException::unknownEnvVariableType($type); |
426
|
|
|
} |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
public function addSharedEnvVariable(string $key, string $value): void |
430
|
|
|
{ |
431
|
|
|
$this->environment[$key] = new EnvVariable($value, EnvVariableTypeEnum::SHARED_ENV_VARIABLE); |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
public function addSharedSecret(string $key, string $value): void |
435
|
|
|
{ |
436
|
|
|
$this->environment[$key] = new EnvVariable($value, EnvVariableTypeEnum::SHARED_SECRET); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
public function addImageEnvVariable(string $key, string $value): void |
440
|
|
|
{ |
441
|
|
|
$this->environment[$key] = new EnvVariable($value, EnvVariableTypeEnum::IMAGE_ENV_VARIABLE); |
442
|
|
|
} |
443
|
|
|
|
444
|
|
|
public function addContainerEnvVariable(string $key, string $value): void |
445
|
|
|
{ |
446
|
|
|
$this->environment[$key] = new EnvVariable($value, EnvVariableTypeEnum::CONTAINER_ENV_VARIABLE); |
447
|
|
|
} |
448
|
|
|
|
449
|
|
|
|
450
|
|
|
/************************ volumes adders & removers **********************/ |
451
|
|
|
|
452
|
|
|
/** @throws ServiceException */ |
453
|
|
|
private function addVolume(string $type, string $source, string $target = '', bool $readOnly = false): void |
454
|
|
|
{ |
455
|
|
|
switch ($type) { |
456
|
|
|
case VolumeTypeEnum::NAMED_VOLUME: |
457
|
|
|
$this->addNamedVolume($source, $target, $readOnly); |
458
|
|
|
break; |
459
|
|
|
case VolumeTypeEnum::BIND_VOLUME: |
460
|
|
|
$this->addBindVolume($source, $target, $readOnly); |
461
|
|
|
break; |
462
|
|
|
case VolumeTypeEnum::TMPFS_VOLUME: |
463
|
|
|
$this->addTmpfsVolume($source); |
464
|
|
|
break; |
465
|
|
|
default: |
466
|
|
|
throw ServiceException::unknownVolumeType($type); |
467
|
|
|
} |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
public function addNamedVolume(string $source, string $target, bool $readOnly = false): void |
471
|
|
|
{ |
472
|
|
|
$this->volumes[] = new NamedVolume($source, $target, $readOnly); |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
public function addBindVolume(string $source, string $target, bool $readOnly = false): void |
476
|
|
|
{ |
477
|
|
|
$this->volumes[] = new BindVolume($source, $target, $readOnly); |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
public function addTmpfsVolume(string $source): void |
481
|
|
|
{ |
482
|
|
|
$this->volumes[] = new TmpfsVolume($source); |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
public function addDockerfileCommand(string $dockerfileCommand): void |
486
|
|
|
{ |
487
|
|
|
$this->dockerfileCommands[] = $dockerfileCommand; |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
private function removeVolumesByType(string $type): void |
491
|
|
|
{ |
492
|
|
|
$filterFunction = function (Volume $vol) use ($type) { |
493
|
|
|
return $vol->getType() !== $type; |
494
|
|
|
}; |
495
|
|
|
$this->volumes = array_values(array_filter($this->volumes, $filterFunction)); |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
public function removeAllBindVolumes(): void |
499
|
|
|
{ |
500
|
|
|
$this->removeVolumesByType(VolumeTypeEnum::BIND_VOLUME); |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
public function removeAllNamedVolumes(): void |
504
|
|
|
{ |
505
|
|
|
$this->removeVolumesByType(VolumeTypeEnum::NAMED_VOLUME); |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
public function removeAllTmpfsVolumes(): void |
509
|
|
|
{ |
510
|
|
|
$this->removeVolumesByType(VolumeTypeEnum::TMPFS_VOLUME); |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
public function removeVolumesBySource(string $source): void |
514
|
|
|
{ |
515
|
|
|
$filterFunction = function (Volume $vol) use ($source) { |
516
|
|
|
return $vol->getSource() !== $source; |
517
|
|
|
}; |
518
|
|
|
$this->volumes = array_values(array_filter($this->volumes, $filterFunction)); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
|
522
|
|
|
/************************ destEnvTypes stuffs **********************/ |
523
|
|
|
|
524
|
|
|
public function addDestEnvType(string $envType, bool $keepTheOtherEnvTypes = true): void |
525
|
|
|
{ |
526
|
|
|
if (!$keepTheOtherEnvTypes) { |
527
|
|
|
$this->destEnvTypes = []; |
528
|
|
|
} |
529
|
|
|
$this->destEnvTypes[] = $envType; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
public function isForDevEnvType(): bool |
533
|
|
|
{ |
534
|
|
|
return empty($this->destEnvTypes) || \in_array(CommonMetadata::ENV_TYPE_DEV, $this->destEnvTypes); |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
public function isForTestEnvType(): bool |
538
|
|
|
{ |
539
|
|
|
return empty($this->destEnvTypes) || \in_array(CommonMetadata::ENV_TYPE_TEST, $this->destEnvTypes); |
540
|
|
|
} |
541
|
|
|
|
542
|
|
|
public function isForProdEnvType(): bool |
543
|
|
|
{ |
544
|
|
|
return empty($this->destEnvTypes) || \in_array(CommonMetadata::ENV_TYPE_PROD, $this->destEnvTypes); |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
public function isForMyEnvType(): bool |
548
|
|
|
{ |
549
|
|
|
$myEnvType = Manifest::getMetadata(CommonMetadata::ENV_TYPE_KEY); |
550
|
|
|
return empty($this->destEnvTypes) || \in_array($myEnvType, $this->destEnvTypes, true); |
551
|
|
|
} |
552
|
|
|
} |
553
|
|
|
|
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 theid
property of an instance of theAccount
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.