Completed
Push — master ( 4032c8...f77c48 )
by Dan Michael O.
02:38
created

Client::request()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php namespace Scriptotek\Sru;
2
3
use Http\Client\Common\Plugin\AuthenticationPlugin;
4
use Http\Client\Common\PluginClient;
5
use Http\Client\HttpClient;
6
use Http\Discovery\HttpClientDiscovery;
7
use Http\Client\Common\Plugin\ErrorPlugin;
8
use Http\Discovery\MessageFactoryDiscovery;
9
use Http\Message\Authentication\BasicAuth;
10
use Http\Message\MessageFactory;
11
12
/**
13
 * SRU client
14
 */
15
class Client
16
{
17
    /** @var HttpClient */
18
    protected $httpClient;
19
20
    /** @var MessageFactory */
21
    protected $messageFactory;
22
23
    /** @var string SRU service base URL */
24
    protected $url;
25
26
    /** @var string Requested schema for the returned records */
27
    protected $schema;
28
29
    /** @var string SRU protocol version */
30
    protected $version;
31
32
    /** @var string Some user agent string to identify our client */
33
    protected $userAgent;
34
35
    /**
36
     * @var string|string[] Proxy configuration details.
37
     *
38
     * Either a string 'host:port' or an
39
     * array('host:port', 'username', 'password').
40
     */
41
    protected $proxy;
42
43
    /**
44
     * @var string[] Array containing username and password
45
     */
46
    protected $credentials;
47
48
    /**
49
     * Create a new client
50
     *
51
     * @param string              $url     Base URL to the SRU service
52
     * @param array               $options Associative array of options
53
     * @param HttpClient          $httpClient
54
     * @param MessageFactory|null $messageFactory
55
     * @throws \ErrorException
56
     */
57
    public function __construct(
58
        $url,
59
        $options = null,
60
        HttpClient $httpClient = null,
61
        MessageFactory $messageFactory = null
62
    ) {
63
        $this->url = $url;
64
        $options = $options ?: array();
65
66
        $plugins = [new ErrorPlugin()];
67
68
        $this->schema = isset($options['schema'])
69
            ? $options['schema']
70
            : 'marcxml';
71
72
        $this->version = isset($options['version'])
73
            ? $options['version']
74
            : '1.1';
75
76
        $this->userAgent = isset($options['user-agent'])
77
            ? $options['user-agent']
78
            : null;
79
80
        if (isset($options['credentials'])) {
81
            $authentication = new BasicAuth($options['credentials'][0], $options['credentials'][1]);
82
            $plugins[] = new AuthenticationPlugin($authentication);
83
        }
84
85
        if (isset($options['proxy'])) {
86
            throw new\ErrorException('Not supported');
87
        }
88
89
        $this->httpClient = new PluginClient($httpClient ?: HttpClientDiscovery::find(), $plugins);
90
        $this->messageFactory = $messageFactory ?: MessageFactoryDiscovery::find();
91
    }
92
93
    /**
94
     * Construct the URL for a CQL query
95
     *
96
     * @param string $cql The CQL query
97
     * @param int $start Start value in result set (optional)
98
     * @param int $count Number of records to request (optional)
99
     * @param array $extraParams Extra GET parameters
100
     * @return string
101
     */
102
    public function urlTo($cql, $start = 1, $count = 10, $extraParams = array())
103
    {
104
        $qs = array(
105
            'operation' => 'searchRetrieve',
106
            'version' => $this->version,
107
            'recordSchema' => $this->schema,
108
            'maximumRecords' => $count,
109
            'query' => $cql
110
        );
111
112
        if ($start != 1) {
113
            // At least the BIBSYS SRU service, specifying startRecord results in
114
            // a less clear error message when there's no results
115
            $qs['startRecord'] = $start;
116
        }
117
118
        foreach ($extraParams as $key => $value) {
119
            $qs[$key] = $value;
120
        }
121
122
        return $this->url . '?' . http_build_query($qs);
123
    }
124
125
    /**
126
     * Get HTTP client configuration options (authentication, proxy, headers)
127
     *
128
     * @return array
129
     */
130
    public function getHttpHeaders()
131
    {
132
        $headers = array(
133
            'Accept' => 'application/xml'
134
        );
135
        if ($this->userAgent) {
136
            $headers['User-Agent'] = $this->userAgent;
137
        }
138
139
        return $headers;
140
    }
141
142
    /**
143
     * Perform a searchRetrieve request
144
     *
145
     * @deprecated
146
     * @param string $cql
147
     * @param int $start Start value in result set (optional)
148
     * @param int $count Number of records to request (optional)
149
     * @param array $extraParams Extra GET parameters
150
     * @return SearchRetrieveResponse
151
     */
152
    public function search($cql, $start = 1, $count = 10, $extraParams = array())
153
    {
154
        $url = $this->urlTo($cql, $start, $count, $extraParams);
155
        $body = $this->request('GET', $url);
156
157
        return new SearchRetrieveResponse($body, $this);
158
    }
159
160
    /**
161
     * Perform a searchRetrieve request and return an iterator over the records
162
     *
163
     * @param string $cql
164
     * @param int $batchSize Number of records to request per request
165
     * @param array $extraParams Extra GET parameters
166
     * @param mixed $httpClient A http client
167
     * @return Records
168
     */
169
    public function all($cql, $batchSize = 10, $extraParams = array(), $httpClient = null)
170
    {
171
        return new Records($cql, $this, $batchSize, $extraParams, $httpClient);
0 ignored issues
show
Unused Code introduced by
The call to Records::__construct() has too many arguments starting with $httpClient.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
172
    }
173
174
    /**
175
     * Alias for `all()`
176
     * @deprecated
177
     * @param $cql
178
     * @param int $batchSize
179
     * @param array $extraParams
180
     * @param null $httpClient
181
     * @return Records
182
     */
183
    public function records($cql, $batchSize = 10, $extraParams = array(), $httpClient = null)
184
    {
185
        return $this->all($cql, $batchSize, $extraParams, $httpClient);
186
    }
187
188
    /**
189
     * Perform a searchRetrieve request and return first record
190
     *
191
     * @param string $cql
192
     * @param array $extraParams Extra GET parameters
193
     * @param mixed $httpClient A http client
194
     * @return Record
195
     */
196
    public function first($cql, $extraParams = array(), $httpClient = null)
197
    {
198
        $recs = new Records($cql, $this, 1, $extraParams, $httpClient);
0 ignored issues
show
Unused Code introduced by
The call to Records::__construct() has too many arguments starting with $httpClient.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
199
        return $recs->numberOfRecords() ? $recs->current() : null;
200
    }
201
202
    /**
203
     * Perform an explain request
204
     *
205
     * @return ExplainResponse
206
     */
207
    public function explain()
208
    {
209
        $url = $this->url . '?' . http_build_query(array(
210
            'operation' => 'explain',
211
            'version' => $this->version,
212
        ));
213
214
        $body = $this->request('GET', $url);
215
216
        return new ExplainResponse($body, $this);
217
    }
218
219
    /**
220
     * @param string $method
221
     * @param string $url
222
     * @return string
223
     */
224
    public function request($method, $url)
225
    {
226
        $request = $this->messageFactory->createRequest($method, $url, $this->getHttpHeaders());
227
        $response = $this->httpClient->sendRequest($request);
228
229
        return (string) $response->getBody();
230
    }
231
}
232