ApiService::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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\StepupMiddlewareClient\Service;
20
21
use GuzzleHttp\Client;
22
use RuntimeException;
23
use Surfnet\StepupMiddlewareClient\Dto\HttpQuery;
24
use Surfnet\StepupMiddlewareClient\Exception\AccessDeniedToResourceException;
25
use Surfnet\StepupMiddlewareClient\Exception\MalformedResponseException;
26
use Surfnet\StepupMiddlewareClient\Exception\ResourceReadException;
27
use Surfnet\StepupMiddlewareClient\Helper\JsonHelper;
28
29
/**
30
 * Provides remote read access to the Middleware's API.
31
 */
32
class ApiService
33
{
34
    /**
35
     * @var Client
36
     */
37
    private $guzzleClient;
38
39
    /**
40
     * @param Client $guzzleClient A Guzzle client preconfigured with base URL and proper authentication.
41
     */
42
    public function __construct(Client $guzzleClient)
43
    {
44
        $this->guzzleClient = $guzzleClient;
45
    }
46
47
    /**
48
     * @param string $path A URL path, optionally containing printf parameters (e.g. '/a/b/%s/d'). The parameters
49
     *               will be URL encoded and formatted into the path string.
50
     *               Example: '/institution/%s/identity/%s', ['institution' => 'ab-cd', 'identity' => 'ef']
51
     * @param array $parameters An array containing the parameters to replace in the path.
52
     * @param HttpQuery $httpQuery|null
0 ignored issues
show
Documentation introduced by
There is no parameter named $httpQuery|null. Did you maybe mean $httpQuery?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
53
     * @return null|mixed Most likely an array structure, null when the resource doesn't exist.
54
     * @throws AccessDeniedToResourceException When the consumer isn't authorised to access given resource.
55
     * @throws ResourceReadException When the server doesn't respond with the resource.
56
     * @throws MalformedResponseException When the server doesn't respond with (well-formed) JSON.
57
     */
58
    public function read($path, array $parameters = [], HttpQuery $httpQuery = null)
59
    {
60
        $resource = $this->buildResourcePath($path, $parameters, $httpQuery);
61
62
        $response = $this->guzzleClient->get($resource, ['http_errors' => false]);
63
        $statusCode = $response->getStatusCode();
64
65
        try {
66
            $body = (string)$response->getBody();
67
            $data = JsonHelper::decode($body);
68
            $errors = isset($data['errors']) && is_array($data['errors']) ? $data['errors'] : [];
69
        } catch (\RuntimeException $e) {
70
            // Malformed JSON body
71
            throw new MalformedResponseException('Cannot read resource: Middleware returned malformed JSON');
72
        }
73
74
        if ($statusCode == 404) {
75
            return null;
76
        }
77
78
        if ($statusCode == 403) {
79
            // Consumer requested resource it is not authorised to access.
80
            throw new AccessDeniedToResourceException($resource, $errors);
81
        }
82
83
        if ($statusCode < 200 || $statusCode >= 300) {
84
            throw new ResourceReadException(
85
                sprintf('Resource could not be read (status code %d)', $statusCode),
86
                $errors
87
            );
88
        }
89
90
        return $data;
91
    }
92
93
    /**
94
     * @param string $path
95
     * @param array $parameters
96
     * @param HttpQuery|null $httpQuery
97
     * @return string
98
     */
99
    private function buildResourcePath($path, array $parameters, HttpQuery $httpQuery = null)
100
    {
101
        if (count($parameters) > 0) {
102
            $resource = vsprintf($path, array_map('urlencode', $parameters));
103
        } else {
104
            $resource = $path;
105
        }
106
107
        if (empty($resource)) {
108
            throw new RuntimeException(
109
                sprintf(
110
                    'Could not construct resource path from path "%s", parameters "%s" and search query "%s"',
111
                    $path,
112
                    implode('","', $parameters),
113
                    $httpQuery ? $httpQuery->toHttpQuery() : ''
114
                )
115
            );
116
        }
117
118
        if ($httpQuery !== null) {
119
            $resource .= $httpQuery->toHttpQuery();
120
        }
121
122
        return $resource;
123
    }
124
}
125