Client   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 12
dl 0
loc 211
rs 10
c 0
b 0
f 0

8 Methods

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

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...
217
        $response = $this->httpClient->sendRequest($request);
218
219
        if ($response->getStatusCode() >= 500 && $response->getStatusCode() < 600) {
220
            throw new ServerErrorException($response->getReasonPhrase(), $request, $response);
221
        }
222
223
        return (string) $response->getBody();
224
    }
225
}
226