Completed
Push — master ( ed3593...2f770f )
by Boy
9s
created

ApiService   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 92
wmc 14
lcom 1
cbo 6
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C read() 0 33 8
B buildResourcePath() 0 25 5
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\ClientInterface;
22
use Surfnet\StepupMiddlewareClient\Exception\AccessDeniedToResourceException;
23
use Surfnet\StepupMiddlewareClient\Exception\MalformedResponseException;
24
use Surfnet\StepupMiddlewareClient\Exception\ResourceReadException;
25
use Surfnet\StepupMiddlewareClient\Dto\HttpQuery;
26
27
/**
28
 * Provides remote read access to the Middleware's API.
29
 */
30
class ApiService
31
{
32
    /**
33
     * @var ClientInterface
34
     */
35
    private $guzzleClient;
36
37
    /**
38
     * @param ClientInterface $guzzleClient A Guzzle client preconfigured with base URL and proper authentication.
39
     */
40
    public function __construct(ClientInterface $guzzleClient)
41
    {
42
        $this->guzzleClient = $guzzleClient;
43
    }
44
45
    /**
46
     * @param string $path A URL path, optionally containing printf parameters (e.g. '/a/b/%s/d'). The parameters
47
     *               will be URL encoded and formatted into the path string.
48
     *               Example: '/institution/%s/identity/%s', ['institution' => 'ab-cd', 'identity' => 'ef']
49
     * @param array $parameters An array containing the parameters to replace in the path.
50
     * @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...
51
     * @return null|mixed Most likely an array structure, null when the resource doesn't exist.
52
     * @throws AccessDeniedToResourceException When the consumer isn't authorised to access given resource.
53
     * @throws ResourceReadException When the server doesn't respond with the resource.
54
     * @throws MalformedResponseException When the server doesn't respond with (well-formed) JSON.
55
     */
56
    public function read($path, array $parameters = [], HttpQuery $httpQuery = null)
57
    {
58
        $resource = $this->buildResourcePath($path, $parameters, $httpQuery);
59
60
        $response = $this->guzzleClient->get($resource, ['exceptions' => false]);
61
        $statusCode = $response->getStatusCode();
62
63
        try {
64
            $data = $response->json();
65
            $errors = isset($data['errors']) && is_array($data['errors']) ? $data['errors'] : [];
66
        } catch (\RuntimeException $e) {
67
            // Malformed JSON body
68
            throw new MalformedResponseException('Cannot read resource: Middleware return malformed JSON');
69
        }
70
71
        if ($statusCode == 404) {
72
            return null;
73
        }
74
75
        if ($statusCode == 403) {
76
            // Consumer requested resource it is not authorised to access.
77
            throw new AccessDeniedToResourceException($resource, $errors);
78
        }
79
80
        if ($statusCode < 200 || $statusCode >= 300) {
81
            throw new ResourceReadException(
82
                sprintf('Resource could not be read (status code %d)', $statusCode),
83
                $errors
84
            );
85
        }
86
87
        return $data;
88
    }
89
90
    /**
91
     * @param string $path
92
     * @param array $parameters
93
     * @param HttpQuery|null $httpQuery
94
     * @return string
95
     */
96
    private function buildResourcePath($path, array $parameters, HttpQuery $httpQuery = null)
97
    {
98
        if (count($parameters) > 0) {
99
            $resource = vsprintf($path, array_map('urlencode', $parameters));
100
        } else {
101
            $resource = $path;
102
        }
103
104
        if (empty($resource)) {
105
            throw new \RuntimeException(
106
                sprintf(
107
                    'Could not construct resource path from path "%s", parameters "%s" and search query "%s"',
108
                    $path,
109
                    implode('","', $parameters),
110
                    $httpQuery ? $httpQuery->toHttpQuery() : ''
111
                )
112
            );
113
        }
114
115
        if ($httpQuery !== null) {
116
            $resource .= $httpQuery->toHttpQuery();
117
        }
118
119
        return $resource;
120
    }
121
}
122