Completed
Pull Request — master (#76)
by Thibaud
03:23
created

GuzzleClient::addRequestParameters()   C

Complexity

Conditions 7
Paths 14

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 24
rs 6.7272
cc 7
eloc 14
nc 14
nop 4
1
<?php
2
3
/*
4
 * This file is part of Phraseanet SDK.
5
 *
6
 * (c) Alchemy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace PhraseanetSDK\Http\Guzzle;
13
14
use Guzzle\Common\Exception\GuzzleException;
15
use Guzzle\Http\Client as Guzzle;
16
use Guzzle\Http\ClientInterface;
17
use Guzzle\Http\Exception\BadResponseException as GuzzleBadResponse;
18
use Guzzle\Http\Exception\CurlException;
19
use Guzzle\Http\Message\EntityEnclosingRequestInterface;
20
use Guzzle\Http\Message\RequestInterface;
21
use PhraseanetSDK\ApplicationInterface;
22
use PhraseanetSDK\Exception\BadResponseException;
23
use PhraseanetSDK\Exception\InvalidArgumentException;
24
use PhraseanetSDK\Exception\RuntimeException;
25
use PhraseanetSDK\Http\Client;
26
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
27
28
class GuzzleClient implements Client
29
{
30
    /**
31
     * @param string $endpoint
32
     * @return string
33
     */
34
    private static function applyEndpointVersion($endpoint)
35
    {
36
        $versionMountPoint = ApplicationInterface::API_MOUNT_POINT;
37
38
        // test if url already end with API_MOUNT_POINT
39
        $mountPoint = substr(trim($endpoint, '/'), -strlen($versionMountPoint));
40
41
        if ($versionMountPoint !== $mountPoint) {
42
            $endpoint = sprintf('%s%s/', trim($endpoint, '/'), $versionMountPoint);
43
44
            return $endpoint;
45
        }
46
47
        return $endpoint;
48
    }
49
50
    /**
51
     * Creates a new instance of GuzzleAdapter
52
     *
53
     * @param string $endpoint
54
     * @param EventSubscriberInterface[] $plugins
55
     * @return static
56
     */
57
    public static function create($endpoint, array $plugins = array()) {
58
59
        if (!is_string($endpoint)) {
60
            throw new InvalidArgumentException('API url endpoint must be a valid url');
61
        }
62
63
        $guzzle = new Guzzle(self::applyEndpointVersion($endpoint));
64
65
        $guzzle->setUserAgent(
66
            sprintf('%s version %s', ApplicationInterface::USER_AGENT, ApplicationInterface::VERSION)
67
        );
68
69
        foreach ($plugins as $plugin) {
70
            $guzzle->addSubscriber($plugin);
71
        }
72
73
        return new static($guzzle);
74
    }
75
76
    /**
77
     * @var ClientInterface
78
     */
79
    private $guzzle;
80
81
    /**
82
     * @param ClientInterface $guzzle
83
     */
84
    public function __construct(ClientInterface $guzzle)
85
    {
86
        $this->guzzle = $guzzle;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     *
92
     * @return ClientInterface
93
     */
94
    public function getGuzzle()
95
    {
96
        return $this->guzzle;
97
    }
98
99
    /**
100
     * Returns the client base URL
101
     *
102
     * @return string
103
     */
104
    public function getBaseUrl()
105
    {
106
        return $this->guzzle->getBaseUrl();
107
    }
108
109
    /**
110
     * Sets the user agent
111
     *
112
     * @param string $userAgent
113
     */
114
    public function setUserAgent($userAgent)
115
    {
116
        $this->guzzle->setUserAgent($userAgent);
117
    }
118
119
    /**
120
     * Performs an HTTP request, returns the body response
121
     *
122
     * @param string $method The method
123
     * @param string $path The path to query
124
     * @param array $query An array of query parameters
125
     * @param array $postFields An array of post fields
126
     * @param array $files An array of post files
127
     * @param array $headers An array of request headers
128
     *
129
     * @return string The response body
130
     *
131
     * @throws BadResponseException
132
     * @throws RuntimeException
133
     */
134
    public function call(
135
        $method,
136
        $path,
137
        array $query = array(),
138
        array $postFields = array(),
139
        array $files = array(),
140
        array $headers = array()
141
    ) {
142
        try {
143
            $request = $this->guzzle->createRequest($method, $path, $headers);
144
            $this->addRequestParameters($request, $query, $postFields, $files);
145
            $response = $request->send();
146
        } catch (CurlException $e) {
147
            throw new RuntimeException($e->getMessage(), $e->getErrorNo(), $e);
148
        } catch (GuzzleBadResponse $e) {
149
            throw BadResponseException::fromGuzzleResponse($e);
150
        } catch (GuzzleException $e) {
151
            throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
152
        }
153
154
        return $response->getBody(true);
155
    }
156
157
    private function addRequestParameters(RequestInterface $request, $query, $postFields, $files)
158
    {
159
        foreach ($query as $name => $value) {
160
            $request->getQuery()->add($name, $value);
161
        }
162
163
        if ($request instanceof EntityEnclosingRequestInterface) {
164
            if ($request->getHeader('Content-Type') == 'application/json') {
165
                $request->getHeaders()->offsetUnset('Content-Type');
166
                $request->setBody(json_encode($postFields));
167
168
                return;
169
            }
170
171
            foreach ($postFields as $name => $value) {
172
                $request->getPostFields()->add($name, $value);
173
            }
174
            foreach ($files as $name => $filename) {
175
                $request->addPostFile($name, $filename);
176
            }
177
        } elseif (0 < count($postFields)) {
178
            throw new InvalidArgumentException('Can not add post fields to GET request');
179
        }
180
    }
181
}
182