Passed
Push — master ( 67b740...62de9e )
by Peter
03:54
created

ApiClient::json()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
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\JsonConverter;
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
     * Data converter instance.
33
     */
34
    protected $converter = null;
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
        $xml = $this->request($this->buildUri($method), $this->prepareParams($method, $params));
83
84
        if (false !== strpos($xml, 'Api-key not accepted')) {
85
            throw new ApiKeyNotAcceptedException;
86
        }
87
88
        if (false !== strpos($xml, 'To avoid misuse of the service')) {
89
            throw new ApiThrottlingException;
90
        }
91
92
        try {
93
            $xml = simplexml_load_string($xml);
94
        } catch (Exception $e) {
95
            throw new InvalidXmlException;
96
        }
97
98
        return $this->converter ? $this->converter->handle($xml) : $xml;
99
    }
100
101
    public function json()
102
    {
103
        $this->converter = new JsonConverter;
104
105
        return $this;
106
    } 
107
108
    /**
109
     * Build the base URI for the API from its endpoint and the resource being requested.
110
     *
111
     * @param $method
112
     * @return string
113
     */
114
    protected function buildUri($method)
115
    {
116
        return $this->apiEndpoint.'/'.ucfirst($method);
117
    }
118
119
    /**
120
     * Almost all API calls require an API Key so we add it to the parameters.
121
     *
122
     * @param $params
123
     * @return string
124
     */
125
    protected function prepareParams($method, $params)
126
    {
127
        if ('ImAlive' == ucfirst($method)) {
128
            return null;
129
        }
130
131
        if (!$this->apiKey) {
132
            throw new MissingApiKeyException;
133
        }
134
135
        return array_merge([ 'apiKey' => $this->apiKey ], $params[0] ?? []);
136
    }
137
138
    /**
139
     * Initialise or inject an instance of the Guzzle client.
140
     *
141
     * @return GuzzleClient
142
     */
143
    protected function initGuzzleClient($guzzleClient = null)
144
    {
145
        $this->guzzleClient = $guzzleClient ?? new GuzzleClient;
146
    }
147
148
    /**
149
     * Make the request to the XML Soccer service and validate response.
150
     *
151
     * @param  string        $uri
152
     * @param  array | null  $params
153
     * @throws RequestFailedException
154
     * @return SimpleXMLElement
155
     */
156
    protected function request($uri, $params)
157
    {
158
        try {
159
            $response = $this->guzzleClient->get($uri, [ 'query' => $params ]);
160
        } catch (Exception $e) {
161
            throw new RequestFailedException;
162
        }
163
164
        return $response->getBody();
165
    }
166
}
167