1
|
|
|
<?php namespace Scriptotek\Sru; |
2
|
|
|
|
3
|
|
|
use GuzzleHttp\Client as HttpClient; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* SRU client |
7
|
|
|
*/ |
8
|
|
|
class Client |
9
|
|
|
{ |
10
|
|
|
/** @var HttpClient */ |
11
|
|
|
protected $httpClient; |
12
|
|
|
|
13
|
|
|
/** @var string SRU service base URL */ |
14
|
|
|
protected $url; |
15
|
|
|
|
16
|
|
|
/** @var string Requested schema for the returned records */ |
17
|
|
|
protected $schema; |
18
|
|
|
|
19
|
|
|
/** @var string SRU protocol version */ |
20
|
|
|
protected $version; |
21
|
|
|
|
22
|
|
|
/** @var string Some user agent string to identify our client */ |
23
|
|
|
protected $userAgent; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var string|string[] Proxy configuration details. |
27
|
|
|
* |
28
|
|
|
* Either a string 'host:port' or an |
29
|
|
|
* array('host:port', 'username', 'password'). |
30
|
|
|
*/ |
31
|
|
|
protected $proxy; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var string[] Array containing username and password |
35
|
|
|
*/ |
36
|
|
|
protected $credentials; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Create a new client |
40
|
|
|
* |
41
|
|
|
* @param string $url Base URL to the SRU service |
42
|
|
|
* @param array $options Associative array of options |
43
|
|
|
* @param HttpClient $httpClient |
44
|
|
|
*/ |
45
|
|
|
public function __construct($url, $options = null, $httpClient = null) |
46
|
|
|
{ |
47
|
|
|
$this->url = $url; |
48
|
|
|
$options = $options ?: array(); |
49
|
|
|
$this->httpClient = $httpClient ?: new HttpClient; |
50
|
|
|
|
51
|
|
|
$this->schema = isset($options['schema']) |
52
|
|
|
? $options['schema'] |
53
|
|
|
: 'marcxml'; |
54
|
|
|
|
55
|
|
|
$this->version = isset($options['version']) |
56
|
|
|
? $options['version'] |
57
|
|
|
: '1.1'; |
58
|
|
|
|
59
|
|
|
$this->userAgent = isset($options['user-agent']) |
60
|
|
|
? $options['user-agent'] |
61
|
|
|
: null; |
62
|
|
|
|
63
|
|
|
$this->credentials = isset($options['credentials']) |
64
|
|
|
? $options['credentials'] |
65
|
|
|
: null; |
66
|
|
|
|
67
|
|
|
$this->proxy = isset($options['proxy']) |
68
|
|
|
? $options['proxy'] |
69
|
|
|
: null; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Construct the URL for a CQL query |
74
|
|
|
* |
75
|
|
|
* @param string $cql The CQL query |
76
|
|
|
* @param int $start Start value in result set (optional) |
77
|
|
|
* @param int $count Number of records to request (optional) |
78
|
|
|
* @param array $extraParams Extra GET parameters |
79
|
|
|
* @return string |
80
|
|
|
*/ |
81
|
|
|
public function urlTo($cql, $start = 1, $count = 10, $extraParams = array()) |
82
|
|
|
{ |
83
|
|
|
$qs = array( |
84
|
|
|
'operation' => 'searchRetrieve', |
85
|
|
|
'version' => $this->version, |
86
|
|
|
'recordSchema' => $this->schema, |
87
|
|
|
'maximumRecords' => $count, |
88
|
|
|
'query' => $cql |
89
|
|
|
); |
90
|
|
|
|
91
|
|
|
if ($start != 1) { |
92
|
|
|
// At least the BIBSYS SRU service, specifying startRecord results in |
93
|
|
|
// a less clear error message when there's no results |
94
|
|
|
$qs['startRecord'] = $start; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
foreach ($extraParams as $key => $value) { |
98
|
|
|
$qs[$key] = $value; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
return $this->url . '?' . http_build_query($qs); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Get HTTP client configuration options (authentication, proxy, headers) |
106
|
|
|
* |
107
|
|
|
* @return array |
108
|
|
|
*/ |
109
|
|
|
public function getHttpOptions() |
110
|
|
|
{ |
111
|
|
|
$headers = array( |
112
|
|
|
'Accept' => 'application/xml' |
113
|
|
|
); |
114
|
|
|
if ($this->userAgent) { |
115
|
|
|
$headers['User-Agent'] = $this->userAgent; |
116
|
|
|
} |
117
|
|
|
$options = array( |
118
|
|
|
'headers' => $headers |
119
|
|
|
); |
120
|
|
|
if ($this->credentials) { |
|
|
|
|
121
|
|
|
$options['auth'] = $this->credentials; |
122
|
|
|
} |
123
|
|
|
if ($this->proxy) { |
124
|
|
|
$options['proxy'] = $this->proxy; |
125
|
|
|
} |
126
|
|
|
return $options; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Perform a searchRetrieve request |
131
|
|
|
* |
132
|
|
|
* @deprecated |
133
|
|
|
* @param string $cql |
134
|
|
|
* @param int $start Start value in result set (optional) |
135
|
|
|
* @param int $count Number of records to request (optional) |
136
|
|
|
* @param array $extraParams Extra GET parameters |
137
|
|
|
* @return SearchRetrieveResponse |
138
|
|
|
*/ |
139
|
|
|
public function search($cql, $start = 1, $count = 10, $extraParams = array()) |
140
|
|
|
{ |
141
|
|
|
$url = $this->urlTo($cql, $start, $count, $extraParams); |
142
|
|
|
$options = $this->getHttpOptions(); |
143
|
|
|
|
144
|
|
|
$response = $this->httpClient->get($url, $options); |
145
|
|
|
$body = (string) $response->getBody(); |
146
|
|
|
|
147
|
|
|
return new SearchRetrieveResponse($body, $this); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Perform a searchRetrieve request and return an iterator over the records |
152
|
|
|
* |
153
|
|
|
* @param string $cql |
154
|
|
|
* @param int $batchSize Number of records to request per request |
155
|
|
|
* @param array $extraParams Extra GET parameters |
156
|
|
|
* @param mixed $httpClient A http client |
157
|
|
|
* @return Records |
158
|
|
|
*/ |
159
|
|
|
public function all($cql, $batchSize = 10, $extraParams = array(), $httpClient = null) |
160
|
|
|
{ |
161
|
|
|
return new Records($cql, $this, $batchSize, $extraParams, $httpClient); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Alias for `all()` |
166
|
|
|
* @deprecated |
167
|
|
|
*/ |
168
|
|
|
public function records($cql, $batchSize = 10, $extraParams = array(), $httpClient = null) |
|
|
|
|
169
|
|
|
{ |
170
|
|
|
return $this->all($cql, $batchSize = 10, $extraParams = array(), $httpClient); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Perform a searchRetrieve request and return first record |
175
|
|
|
* |
176
|
|
|
* @param string $cql |
177
|
|
|
* @param array $extraParams Extra GET parameters |
178
|
|
|
* @param mixed $httpClient A http client |
179
|
|
|
* @return Record |
180
|
|
|
*/ |
181
|
|
|
public function first($cql, $extraParams = array(), $httpClient = null) |
182
|
|
|
{ |
183
|
|
|
$recs = new Records($cql, $this, 1, $extraParams, $httpClient); |
184
|
|
|
return $recs->numberOfRecords() ? $recs->current() : null; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Perform an explain request |
189
|
|
|
* |
190
|
|
|
* @return ExplainResponse |
191
|
|
|
*/ |
192
|
|
|
public function explain() |
193
|
|
|
{ |
194
|
|
|
$url = $this->url . '?' . http_build_query(array( |
195
|
|
|
'operation' => 'explain', |
196
|
|
|
'version' => $this->version, |
197
|
|
|
)); |
198
|
|
|
$options = $this->getHttpOptions(); |
199
|
|
|
|
200
|
|
|
$response = $this->httpClient->get($url, $options); |
201
|
|
|
$body = (string) $response->getBody(); |
202
|
|
|
|
203
|
|
|
return new ExplainResponse($body, $this); |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.