Passed
Pull Request — master (#139)
by Matt
03:33
created

Serializer::__invoke()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
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 Psr\Http\Message\RequestInterface;
16
17
/**
18
 * Serializes requests for a given command.
19
 */
20
class Serializer
21
{
22
    /** @var RequestLocationInterface[] */
23
    private $locations;
24
25
    /** @var DescriptionInterface */
26
    private $description;
27
28
    /**
29
     * @param DescriptionInterface       $description
30
     * @param RequestLocationInterface[] $requestLocations Extra request locations
31
     */
32 1
    public function __construct(
33
        DescriptionInterface $description,
34
        array $requestLocations = []
35
    ) {
36 1
        static $defaultRequestLocations;
37 1
        if (!$defaultRequestLocations) {
38
            $defaultRequestLocations = [
39
                'body'      => new BodyLocation(),
40
                'query'     => new QueryLocation(),
41
                'header'    => new HeaderLocation(),
42
                'json'      => new JsonLocation(),
43
                'xml'       => new XmlLocation(),
44
                'formParam' => new FormParamLocation(),
45
                'multipart' => new MultiPartLocation(),
46
            ];
47
        }
48
49 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...
50 1
        $this->description = $description;
51 1
    }
52
53
    /**
54
     * @param CommandInterface $command
55
     * @return RequestInterface
56
     */
57 1
    public function __invoke(CommandInterface $command)
58
    {
59 1
        $request = $this->createRequest($command);
60 1
        return $this->prepareRequest($command, $request);
61
    }
62
63
    /**
64
     * Prepares a request for sending using location visitors
65
     *
66
     * @param CommandInterface $command
67
     * @param RequestInterface $request Request being created
68
     * @return RequestInterface
69
     * @throws \RuntimeException If a location cannot be handled
70
     */
71 1
    protected function prepareRequest(
72
        CommandInterface $command,
73
        RequestInterface $request
74
    ) {
75 1
        $visitedLocations = [];
76 1
        $operation = $this->description->getOperation($command->getName());
77
78
        // Visit each actual parameter
79 1
        foreach ($operation->getParams() as $name => $param) {
80
            /* @var Parameter $param */
81 1
            $location = $param->getLocation();
82
            // Skip parameters that have not been set or are URI location
83 1
            if ($location == 'uri' || !$command->hasParam($name)) {
84 1
                continue;
85
            }
86
            if (!isset($this->locations[$location])) {
87
                throw new \RuntimeException("No location registered for $name");
88
            }
89
            $visitedLocations[$location] = true;
90
            $request = $this->locations[$location]->visit($command, $request, $param);
91 1
        }
92
93
        // Ensure that the after() method is invoked for additionalParameters
94
        /** @var Parameter $additional */
95 1
        if ($additional = $operation->getAdditionalParameters()) {
96
            $visitedLocations[$additional->getLocation()] = true;
97
        }
98
99
        // Call the after() method for each visited location
100 1
        foreach (array_keys($visitedLocations) as $location) {
101
            $request = $this->locations[$location]->after($command, $request, $operation);
102 1
        }
103
104 1
        return $request;
105
    }
106
107
    /**
108
     * Create a request for the command and operation
109
     *
110
     * @param CommandInterface $command
111
     *
112
     * @return RequestInterface
113
     * @throws \RuntimeException
114
     */
115 1
    protected function createRequest(CommandInterface $command)
116
    {
117 1
        $operation = $this->description->getOperation($command->getName());
118
119
        // If command does not specify a template, assume the client's base URL.
120 1
        if (null === $operation->getUri()) {
121
            return new Request(
122
                $operation->getHttpMethod(),
123
                $this->description->getBaseUri()
124
            );
125
        }
126
127 1
        return $this->createCommandWithUri($operation, $command);
128
    }
129
130
    /**
131
     * Create a request for an operation with a uri merged onto a base URI
132
     *
133
     * @param \GuzzleHttp\Command\Guzzle\Operation $operation
134
     * @param \GuzzleHttp\Command\CommandInterface $command
135
     *
136
     * @return \GuzzleHttp\Psr7\Request
137
     */
138 1
    private function createCommandWithUri(
139
        Operation $operation,
140
        CommandInterface $command
141
    ) {
142
        // Get the path values and use the client config settings
143 1
        $variables = [];
144 1
        foreach ($operation->getParams() as $name => $arg) {
145
            /* @var Parameter $arg */
146 1
            if ($arg->getLocation() == 'uri') {
147 1
                if (isset($command[$name])) {
148 1
                    $variables[$name] = $arg->filter($command[$name]);
149 1
                    if (!is_array($variables[$name])) {
150 1
                        $variables[$name] = (string) $variables[$name];
151 1
                    }
152 1
                }
153 1
            }
154 1
        }
155
156
        // Expand the URI template.
157 1
        $uri = \GuzzleHttp\uri_template($operation->getUri(), $variables);
158
159 1
        return new Request(
160 1
            $operation->getHttpMethod(),
161 1
            Uri::resolve($this->description->getBaseUri(), $uri)
162 1
        );
163
    }
164
}
165