Serializer::prepareRequest()   B
last analyzed

Complexity

Conditions 7
Paths 13

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 9.8821

Importance

Changes 0
Metric Value
cc 7
nc 13
nop 2
dl 0
loc 35
ccs 11
cts 18
cp 0.6111
crap 9.8821
rs 8.4266
c 0
b 0
f 0
1
<?php
2
namespace GuzzleHttp\Command\Guzzle;
3
4
use GuzzleHttp\Command\CommandInterface;
5
use GuzzleHttp\Command\Guzzle\RequestLocation\BodyLocation;
6
use GuzzleHttp\Command\Guzzle\RequestLocation\FormParamLocation;
7
use GuzzleHttp\Command\Guzzle\RequestLocation\HeaderLocation;
8
use GuzzleHttp\Command\Guzzle\RequestLocation\JsonLocation;
9
use GuzzleHttp\Command\Guzzle\RequestLocation\MultiPartLocation;
10
use GuzzleHttp\Command\Guzzle\RequestLocation\QueryLocation;
11
use GuzzleHttp\Command\Guzzle\RequestLocation\RequestLocationInterface;
12
use GuzzleHttp\Command\Guzzle\RequestLocation\XmlLocation;
13
use GuzzleHttp\Psr7\Request;
14
use GuzzleHttp\Psr7\Uri;
15
use GuzzleHttp\Psr7\UriResolver;
16
use GuzzleHttp\UriTemplate\UriTemplate;
17
use Psr\Http\Message\RequestInterface;
18
19
/**
20
 * Serializes requests for a given command.
21
 */
22
class Serializer
23
{
24
    /** @var RequestLocationInterface[] */
25
    private $locations;
26
27
    /** @var DescriptionInterface */
28
    private $description;
29
30
    /**
31
     * @param DescriptionInterface       $description
32 1
     * @param RequestLocationInterface[] $requestLocations Extra request locations
33
     */
34
    public function __construct(
35
        DescriptionInterface $description,
36 1
        array $requestLocations = []
37 1
    ) {
38
        static $defaultRequestLocations;
39
        if (!$defaultRequestLocations) {
40
            $defaultRequestLocations = [
41
                'body'      => new BodyLocation(),
42
                'query'     => new QueryLocation(),
43
                'header'    => new HeaderLocation(),
44
                'json'      => new JsonLocation(),
45
                'xml'       => new XmlLocation(),
46
                'formParam' => new FormParamLocation(),
47
                'multipart' => new MultiPartLocation(),
48
            ];
49 1
        }
50 1
51 1
        $this->locations = $requestLocations + $defaultRequestLocations;
0 ignored issues
show
Documentation Bug introduced by
It seems like $requestLocations + $defaultRequestLocations of type array<integer|string,obj...uestLocationInterface>> is incompatible with the declared type array<integer,object<Guz...uestLocationInterface>> of property $locations.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
52
        $this->description = $description;
53
    }
54
55
    /**
56
     * @param CommandInterface $command
57 1
     * @return RequestInterface
58
     */
59 1
    public function __invoke(CommandInterface $command)
60 1
    {
61
        $request = $this->createRequest($command);
62
        return $this->prepareRequest($command, $request);
63
    }
64
65
    /**
66
     * Prepares a request for sending using location visitors
67
     *
68
     * @param CommandInterface $command
69
     * @param RequestInterface $request Request being created
70
     * @return RequestInterface
71 1
     * @throws \RuntimeException If a location cannot be handled
72
     */
73
    protected function prepareRequest(
74
        CommandInterface $command,
75 1
        RequestInterface $request
76 1
    ) {
77
        $visitedLocations = [];
78
        $operation = $this->description->getOperation($command->getName());
79 1
80
        // Visit each actual parameter
81 1
        foreach ($operation->getParams() as $name => $param) {
82
            /* @var Parameter $param */
83 1
            $location = $param->getLocation();
84 1
            // Skip parameters that have not been set or are URI location
85
            if ($location == 'uri' || !$command->hasParam($name)) {
86
                continue;
87
            }
88
            if (!isset($this->locations[$location])) {
89
                throw new \RuntimeException("No location registered for $name");
90
            }
91 1
            $visitedLocations[$location] = true;
92
            $request = $this->locations[$location]->visit($command, $request, $param);
93
        }
94
95 1
        // Ensure that the after() method is invoked for additionalParameters
96
        /** @var Parameter $additional */
97
        if ($additional = $operation->getAdditionalParameters()) {
98
            $visitedLocations[$additional->getLocation()] = true;
99
        }
100 1
101
        // Call the after() method for each visited location
102 1
        foreach (array_keys($visitedLocations) as $location) {
103
            $request = $this->locations[$location]->after($command, $request, $operation);
104 1
        }
105
106
        return $request;
107
    }
108
109
    /**
110
     * Create a request for the command and operation
111
     *
112
     * @param CommandInterface $command
113
     *
114
     * @return RequestInterface
115 1
     * @throws \RuntimeException
116
     */
117 1
    protected function createRequest(CommandInterface $command)
118
    {
119
        $operation = $this->description->getOperation($command->getName());
120 1
121
        // If command does not specify a template, assume the client's base URL.
122
        if (null === $operation->getUri()) {
123
            return new Request(
124
                $operation->getHttpMethod(),
125
                $this->description->getBaseUri()
126
            );
127 1
        }
128
129
        return $this->createCommandWithUri($operation, $command);
130
    }
131
132
    /**
133
     * Create a request for an operation with a uri merged onto a base URI
134
     *
135
     * @param \GuzzleHttp\Command\Guzzle\Operation $operation
136
     * @param \GuzzleHttp\Command\CommandInterface $command
137
     *
138 1
     * @return \GuzzleHttp\Psr7\Request
139
     */
140
    private function createCommandWithUri(
141
        Operation $operation,
142
        CommandInterface $command
143 1
    ) {
144 1
        // Get the path values and use the client config settings
145
        $variables = [];
146 1
        foreach ($operation->getParams() as $name => $arg) {
147 1
            /* @var Parameter $arg */
148 1
            if ($arg->getLocation() == 'uri') {
149 1
                if (isset($command[$name])) {
150 1
                    $variables[$name] = $arg->filter($command[$name]);
151 1
                    if (!is_array($variables[$name])) {
152 1
                        $variables[$name] = (string) $variables[$name];
153 1
                    }
154 1
                }
155
            }
156
        }
157 1
158
        // Expand the URI template.
159 1
        $uri = new Uri(UriTemplate::expand($operation->getUri(), $variables));
160 1
161 1
        return new Request(
162 1
            $operation->getHttpMethod() ?: 'GET',
163
            UriResolver::resolve($this->description->getBaseUri(), $uri)
164
        );
165
    }
166
}
167