assertIsValidCommandStructure()   B
last analyzed

Complexity

Conditions 9
Paths 6

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 12
nc 6
nop 1
dl 0
loc 24
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\Request;
20
21
use Surfnet\StepupMiddleware\ApiBundle\Exception\BadCommandRequestException;
22
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\AbstractCommand;
23
use Surfnet\StepupMiddleware\CommandHandlingBundle\Command\Command;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
26
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
27
28
class CommandValueResolver implements ValueResolverInterface
29
{
30
    /**
31
     * @return AbstractCommand[]
32
     */
33
    public function resolve(Request $request, ArgumentMetadata $argument): iterable
34
    {
35
        $argumentType = $argument->getType();
36
        if (!$argumentType
0 ignored issues
show
Coding Style introduced by
The first expression of a multi-line control structure must be on the line after the opening parenthesis
Loading history...
37
            || (!is_subclass_of($argumentType, Command::class, true) && Command::class !== $argumentType)
38
        ) {
39
            return [];
40
        }
41
42
        $data = json_decode($request->getContent(), true);
43
44
        $this->assertIsValidCommandStructure($data);
45
46
        $commandNameParts = [];
47
        $found = preg_match('~^(\w+):([\w\\.]+)$~', (string)$data['command']['name'], $commandNameParts);
48
        if ($found !== 1) {
49
            $message = sprintf('Command does not have a valid command name %s', (string)$data['command']['name']);
50
            throw new BadCommandRequestException(
51
                [$message],
52
                $message,
53
            );
54
        }
55
        $commandClassName = sprintf(
56
            'Surfnet\StepupMiddleware\CommandHandlingBundle\%s\Command\%sCommand',
57
            $commandNameParts[1],
58
            str_replace('.', '\\', $commandNameParts[2]),
59
        );
60
61
        /** @var AbstractCommand $command */
62
        $command = new $commandClassName;
0 ignored issues
show
Coding Style introduced by
Parentheses must be used when instantiating a new class
Loading history...
63
        $command->UUID = (string)$data['command']['uuid'];
64
65
        foreach ((array)$data['command']['payload'] as $property => $value) {
66
            $properlyCasedProperty = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', (string)$property))));
67
            $command->$properlyCasedProperty = $value;
68
        }
69
70
        return [$command];
71
    }
72
73
    /**
74
     * @throws BadCommandRequestException
75
     */
76
    private function assertIsValidCommandStructure(mixed $data): void
77
    {
78
        if (!is_array($data)) {
79
            $type = gettype($data);
80
81
            throw new BadCommandRequestException(
82
                [sprintf('Command is not valid: body must be a JSON object, but is of type %s', $type)],
83
            );
84
        }
85
86
        if (!isset($data['command'])) {
87
            throw new BadCommandRequestException(["Required parameter 'command' is not set."]);
88
        }
89
90
        if (!isset($data['command']['name']) || !is_string($data['command']['name'])) {
91
            throw new BadCommandRequestException(["Required command parameter 'name' is not set or not a string."]);
92
        }
93
94
        if (!isset($data['command']['uuid']) || !is_string($data['command']['uuid'])) {
95
            throw new BadCommandRequestException(["Required command parameter 'uuid' is not set or not a string."]);
96
        }
97
98
        if (!isset($data['command']['payload']) || !is_array($data['command']['payload'])) {
99
            throw new BadCommandRequestException(["Required command parameter 'payload' is not set or not an object."]);
100
        }
101
    }
102
}
103