Passed
Push — master ( dd75d0...cfee86 )
by Peter
02:55
created

ApiClient::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace PeterColes\XmlSoccer;
4
5
use Exception;
6
use GuzzleHttp\Client as GuzzleClient;
7
use PeterColes\XmlSoccer\Converters\ObjectConverter;
8
use PeterColes\XmlSoccer\Exceptions\ApiKeyNotAcceptedException;
9
use PeterColes\XmlSoccer\Exceptions\ApiThrottlingException;
10
use PeterColes\XmlSoccer\Exceptions\InvalidXmlException;
11
use PeterColes\XmlSoccer\Exceptions\MissingApiKeyException;
12
use PeterColes\XmlSoccer\Exceptions\RequestFailedException;
13
14
class ApiClient
15
{
16
    /**
17
     * Default API endpoint.
18
     */
19
    protected $apiEndpoint;
20
21
    /**
22
     * Subscriber's API key.
23
     */
24
    protected $apiKey;
25
26
    /**
27
     * Guzzle client instance.
28
     */
29
    protected $guzzleClient;
30
31
    /**
32
     * The raw XML response returned from the last XMLSoccer request.
33
     */
34
    protected $response;
35
36
    /**
37
     * Optional (recommended) setting of an API key when a new instance is instantiated.
38
     * Setting the API endpoint, default or demo according to the (optional) parameter.
39
     * Advanced users may wish to a Guzzle client with their own configuration settings
40
     * but this will rarely be needed.
41
     *
42
     * @param string | null $apiKey
43
     * @param boolean       $demo
44
     * @param GuzzleClient  $guzzleClient
45
     */
46
    public function __construct($apiKey = null, $demo = false, $guzzleClient = null)
47
    {
48
        $this->setApiKey($apiKey);
49
        $this->setApiEndpoint($demo);
50
        $this->initGuzzleClient($guzzleClient);
51
    }
52
53
    /**
54
     * Override default API endpoint.
55
     *
56
     * @param $apiEndpoint
57
     */
58
    public function setApiEndpoint($demo = false)
59
    {
60
        $this->apiEndpoint = 'http://www.xmlsoccer.com/FootballData'.($demo ? 'Demo' : '').'.asmx';
61
    }
62
63
    /**
64
     * Set or override the API key.
65
     *
66
     * @param $apiKey
67
     */
68
    public function setApiKey($apiKey)
69
    {
70
        $this->apiKey = $apiKey;
71
    }
72
73
    /**
74
     * Accept the requested method and its parameters, make the request to XML Soccer and validate the response.
75
     *
76
     * @param $name
77
     * @param $params
78
     * @return SimpleXMLElement
79
     */
80
    public function __call($method, $params)
81
    {
82
        $this->response = $this->request($this->buildUri($method), $this->prepareParams($method, $params));
83
84
        if (false !== strpos($this->response, 'Api-key not accepted')) {
85
            throw new ApiKeyNotAcceptedException;
86
        }
87
88
        if (false !== strpos($this->response, 'To avoid misuse of the service')) {
89
            throw new ApiThrottlingException;
90
        }
91
92
        return $this;
93
    }
94
95
    public function get()
96
    {
97
        return $this->response;
98
    }
99
100
    public function xml()
101
    {
102
        try {
103
            $xmlObject = simplexml_load_string($this->response);
104
        } catch (Exception $e) {
105
            throw new InvalidXmlException;
106
        }
107
108
        return $xmlObject;
109
    }
110
111
    public function object()
112
    {
113
        return (new ObjectConverter)->handle($this->xml());
114
    }
115
116
    public function json()
117
    {
118
        return json_encode($this->object());
119
    } 
120
121
    /**
122
     * Build the base URI for the API from its endpoint and the resource being requested.
123
     *
124
     * @param $method
125
     * @return string
126
     */
127
    protected function buildUri($method)
128
    {
129
        return $this->apiEndpoint.'/'.ucfirst($method);
130
    }
131
132
    /**
133
     * Almost all API calls require an API Key so we add it to the parameters.
134
     *
135
     * @param $params
136
     * @return string
137
     */
138
    protected function prepareParams($method, $params)
139
    {
140
        if ('ImAlive' == ucfirst($method)) {
141
            return null;
142
        }
143
144
        if (!$this->apiKey) {
145
            throw new MissingApiKeyException;
146
        }
147
148
        return array_merge([ 'apiKey' => $this->apiKey ], $params[ 0 ] ?? [ ]);
149
    }
150
151
    /**
152
     * Initialise or inject an instance of the Guzzle client.
153
     *
154
     * @return GuzzleClient
155
     */
156
    protected function initGuzzleClient($guzzleClient = null)
157
    {
158
        $this->guzzleClient = $guzzleClient ?? new GuzzleClient;
159
    }
160
161
    /**
162
     * Make the request to the XML Soccer service and validate response.
163
     *
164
     * @param  string        $uri
165
     * @param  array | null  $params
166
     * @throws RequestFailedException
167
     * @return SimpleXMLElement
168
     */
169
    protected function request($uri, $params)
170
    {
171
        try {
172
            $response = $this->guzzleClient->get($uri, [ 'query' => $params ]);
173
        } catch (Exception $e) {
174
            throw new RequestFailedException;
175
        }
176
177
        return $response->getBody();
178
    }
179
}
180