Completed
Push — master ( 494ce5...3a9e82 )
by Jakob
01:22
created

Client::query()   D

Complexity

Conditions 9
Paths 18

Size

Total Lines 44
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 4.909
c 0
b 0
f 0
cc 9
eloc 27
nc 18
nop 2
1
<?php declare(strict_types=1);
2
  
3
namespace JSKOS;
4
  
5
use Http\Client\HttpClient;
6
use Http\Discovery\HttpClientDiscovery;
7
use Http\Discovery\MessageFactoryDiscovery;
8
use InvalidArgumentException;
9
10
/**
11
 * JSKOS API Client
12
 */
13
class Client extends Service
14
{
15
    protected $baseUrl;
16
	protected $httpClient;
17
    protected $requestFactory;
18
19
    public function __construct(
20
        string $baseUrl,
21
        HttpClient $client=null, 
22
        RequestFactory $requestFactory=null
23
    )
24
    {
25
		$this->baseUrl        = $baseUrl;
26
		$this->httpClient     = $client ?: HttpClientDiscovery::find();
27
		$this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find();
28
	}
29
30
	public function query(array $query=[], string $path=''): Result {
31
		$url = $this->baseUrl . $path;
32
                
33
		if (count($query)) {
34
			$url .= '?' . http_build_query($query);
35
		}
36
37
        $request = $this->requestFactory->createRequest('GET', $url, []);
38
		$response = $this->httpClient->sendRequest($request);
39
40
        if ($response->getStatusCode() != 200) {
41
            throw new Error(502, 'Unsuccessful HTTP response');
42
        }
43
44
        $body = (string)$response->getBody();
45
        if (!preg_match('/\s*\[/m', $body)) {
46
            throw new Error(502, 'Failed to parse JSON array');
47
        }
48
49
        $data = json_decode($body, true);        
50
        if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
51
            throw new Error(502, 'Failed to parse JSON', json_last_error_msg());
52
        }
53
54
        $result = new Result();
55
        if ($response->hasHeader('X-Total-Count')) {
56
            $result->setTotalCount(intval($response->getHeaderLine('X-Total-Count')));
57
        } else {
58
            $result->unsetTotalCount();
59
        }
60
61
        foreach ($data as $n => $resource) {
62
            $class = Resource::guessClassFromTypes($resource['type'] ?? []) 
63
                ?? Concept::class;
64
            try {
65
                # TODO: enable strict parsing?
66
                $result->append(new $class($data[$n]));
67
            } catch(InvalidArgumentException $e) {
68
                throw new Error(502, 'JSON response is no valid JSKOS');
69
            }
70
        }
71
72
        return $result;
73
	}
74
}
75