Completed
Push — master ( 3550b3...3cf4c5 )
by Dan Michael O.
04:15
created

Client   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 7
Bugs 1 Features 0
Metric Value
wmc 22
c 7
b 1
f 0
lcom 1
cbo 12
dl 0
loc 209
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
D __construct() 0 40 10
A urlTo() 0 22 3
A search() 0 7 1
A all() 0 4 1
A records() 0 4 1
A first() 0 5 2
A explain() 0 11 1
A request() 0 11 3
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\Exception\ServerErrorException;
8
use Http\Client\Common\Plugin\ErrorPlugin;
9
use Http\Discovery\MessageFactoryDiscovery;
10
use Http\Message\Authentication\BasicAuth;
11
use Http\Message\MessageFactory;
12
13
/**
14
 * SRU client
15
 */
16
class Client
17
{
18
    /** @var HttpClient */
19
    protected $httpClient;
20
21
    /** @var MessageFactory */
22
    protected $messageFactory;
23
24
    /** @var string SRU service base URL */
25
    protected $url;
26
27
    /** @var string Requested schema for the returned records */
28
    protected $schema;
29
30
    /** @var string SRU protocol version */
31
    protected $version;
32
33
    /** @var string Some user agent string to identify our client */
34
    protected $userAgent;
35
36
    /** @var array Custom headers */
37
    public $headers;
38
39
    /**
40
     * @var string|string[] Proxy configuration details.
41
     *
42
     * Either a string 'host:port' or an
43
     * array('host:port', 'username', 'password').
44
     */
45
    protected $proxy;
46
47
    /**
48
     * @var string[] Array containing username and password
49
     */
50
    protected $credentials;
51
52
    /**
53
     * Create a new client
54
     *
55
     * @param string              $url     Base URL to the SRU service
56
     * @param array               $options Associative array of options
57
     * @param HttpClient          $httpClient
58
     * @param MessageFactory|null $messageFactory
59
     * @throws \ErrorException
60
     */
61
    public function __construct(
62
        $url,
63
        $options = null,
64
        HttpClient $httpClient = null,
65
        MessageFactory $messageFactory = null
66
    ) {
67
        $this->url = $url;
68
        $options = $options ?: array();
69
70
        $plugins = [];
71
72
        $this->schema = isset($options['schema'])
73
            ? $options['schema']
74
            : 'marcxml';
75
76
        $this->version = isset($options['version'])
77
            ? $options['version']
78
            : '1.1';
79
80
        $this->headers = isset($options['headers'])
81
            ? $options['headers']
82
            : ['Accept' => 'application/xml'];
83
84
        if (isset($options['user-agent'])) {
85
            // legacy option
86
            $this->headers['User-Agent'] = $options['user-agent'];
87
        }
88
89
        if (isset($options['credentials'])) {
90
            $authentication = new BasicAuth($options['credentials'][0], $options['credentials'][1]);
91
            $plugins[] = new AuthenticationPlugin($authentication);
92
        }
93
94
        if (isset($options['proxy'])) {
95
            throw new\ErrorException('Not supported');
96
        }
97
98
        $this->httpClient = new PluginClient($httpClient ?: HttpClientDiscovery::find(), $plugins);
99
        $this->messageFactory = $messageFactory ?: MessageFactoryDiscovery::find();
100
    }
101
102
    /**
103
     * Construct the URL for a CQL query
104
     *
105
     * @param string $cql The CQL query
106
     * @param int $start Start value in result set (optional)
107
     * @param int $count Number of records to request (optional)
108
     * @param array $extraParams Extra GET parameters
109
     * @return string
110
     */
111
    public function urlTo($cql, $start = 1, $count = 10, $extraParams = array())
112
    {
113
        $qs = array(
114
            'operation' => 'searchRetrieve',
115
            'version' => $this->version,
116
            'recordSchema' => $this->schema,
117
            'maximumRecords' => $count,
118
            'query' => $cql
119
        );
120
121
        if ($start != 1) {
122
            // At least the BIBSYS SRU service, specifying startRecord results in
123
            // a less clear error message when there's no results
124
            $qs['startRecord'] = $start;
125
        }
126
127
        foreach ($extraParams as $key => $value) {
128
            $qs[$key] = $value;
129
        }
130
131
        return $this->url . '?' . http_build_query($qs);
132
    }
133
134
    /**
135
     * Perform a searchRetrieve request
136
     *
137
     * @deprecated
138
     * @param string $cql
139
     * @param int $start Start value in result set (optional)
140
     * @param int $count Number of records to request (optional)
141
     * @param array $extraParams Extra GET parameters
142
     * @return SearchRetrieveResponse
143
     */
144
    public function search($cql, $start = 1, $count = 10, $extraParams = array())
145
    {
146
        $url = $this->urlTo($cql, $start, $count, $extraParams);
147
        $body = $this->request('GET', $url);
148
149
        return new SearchRetrieveResponse($body, $this);
150
    }
151
152
    /**
153
     * Perform a searchRetrieve request and return an iterator over the records
154
     *
155
     * @param string $cql
156
     * @param int $batchSize Number of records to request per request
157
     * @param array $extraParams Extra GET parameters
158
     * @return Records
159
     */
160
    public function all($cql, $batchSize = 10, $extraParams = array())
161
    {
162
        return new Records($cql, $this, $batchSize, $extraParams);
163
    }
164
165
    /**
166
     * Alias for `all()`
167
     * @deprecated
168
     * @param $cql
169
     * @param int $batchSize
170
     * @param array $extraParams
171
     * @return Records
172
     */
173
    public function records($cql, $batchSize = 10, $extraParams = array())
174
    {
175
        return $this->all($cql, $batchSize, $extraParams);
176
    }
177
178
    /**
179
     * Perform a searchRetrieve request and return first record
180
     *
181
     * @param string $cql
182
     * @param array $extraParams Extra GET parameters
183
     * @return Record
184
     */
185
    public function first($cql, $extraParams = array())
186
    {
187
        $recs = new Records($cql, $this, 1, $extraParams);
188
        return $recs->numberOfRecords() ? $recs->current() : null;
189
    }
190
191
    /**
192
     * Perform an explain request
193
     *
194
     * @return ExplainResponse
195
     */
196
    public function explain()
197
    {
198
        $url = $this->url . '?' . http_build_query(array(
199
            'operation' => 'explain',
200
            'version' => $this->version,
201
        ));
202
203
        $body = $this->request('GET', $url);
204
205
        return new ExplainResponse($body, $this);
206
    }
207
208
    /**
209
     * @param string $method
210
     * @param string $url
211
     * @return string
212
     */
213
    public function request($method, $url)
214
    {
215
        $request = $this->messageFactory->createRequest($method, $url, $this->headers);
216
        $response = $this->httpClient->sendRequest($request);
217
218
        if ($response->getStatusCode() >= 500 && $response->getStatusCode() < 600) {
219
            throw new ServerErrorException($response->getReasonPhrase(), $request, $response);
220
        }
221
222
        return (string) $response->getBody();
223
    }
224
}
225