|
1
|
|
|
<?php namespace Scriptotek\Sru; |
|
2
|
|
|
|
|
3
|
|
|
use Danmichaelo\QuiteSimpleXMLElement\QuiteSimpleXMLElement; |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* Generic SRU response |
|
7
|
|
|
*/ |
|
8
|
|
|
class Response implements ResponseInterface |
|
9
|
|
|
{ |
|
10
|
|
|
public static $errorMessages = array( |
|
11
|
|
|
'info:srw/diagnostic/1/1' => 'General system error', |
|
12
|
|
|
'info:srw/diagnostic/1/2' => 'System temporarily unavailable', |
|
13
|
|
|
'info:srw/diagnostic/1/3' => 'Authentication error', |
|
14
|
|
|
'info:srw/diagnostic/1/4' => 'Unsupported operation', |
|
15
|
|
|
'info:srw/diagnostic/1/5' => 'Unsupported version', |
|
16
|
|
|
'info:srw/diagnostic/1/6' => 'Unsupported parameter value', |
|
17
|
|
|
'info:srw/diagnostic/1/7' => 'Mandatory parameter not supplied', |
|
18
|
|
|
'info:srw/diagnostic/1/8' => 'Unsupported parameter', |
|
19
|
|
|
'info:srw/diagnostic/1/10' => 'Query syntax error', |
|
20
|
|
|
'info:srw/diagnostic/1/12' => 'Too many characters in query', |
|
21
|
|
|
'info:srw/diagnostic/1/13' => 'Invalid or unsupported use of parentheses', |
|
22
|
|
|
'info:srw/diagnostic/1/14' => 'Invalid or unsupported use of quotes', |
|
23
|
|
|
'info:srw/diagnostic/1/15' => 'Unsupported context set', |
|
24
|
|
|
'info:srw/diagnostic/1/16' => 'Unsupported index', |
|
25
|
|
|
'info:srw/diagnostic/1/18' => 'Unsupported combination of indexes', |
|
26
|
|
|
'info:srw/diagnostic/1/19' => 'Unsupported relation', |
|
27
|
|
|
'info:srw/diagnostic/1/20' => 'Unsupported relation modifier', |
|
28
|
|
|
'info:srw/diagnostic/1/21' => 'Unsupported combination of relation modifers', |
|
29
|
|
|
'info:srw/diagnostic/1/22' => 'Unsupported combination of relation and index', |
|
30
|
|
|
'info:srw/diagnostic/1/23' => 'Too many characters in term', |
|
31
|
|
|
'info:srw/diagnostic/1/24' => 'Unsupported combination of relation and term', |
|
32
|
|
|
'info:srw/diagnostic/1/26' => 'Non special character escaped in term', |
|
33
|
|
|
'info:srw/diagnostic/1/27' => 'Empty term unsupported', |
|
34
|
|
|
'info:srw/diagnostic/1/28' => 'Masking character not supported', |
|
35
|
|
|
'info:srw/diagnostic/1/29' => 'Masked words too short', |
|
36
|
|
|
'info:srw/diagnostic/1/30' => 'Too many masking characters in term', |
|
37
|
|
|
'info:srw/diagnostic/1/31' => 'Anchoring character not supported', |
|
38
|
|
|
'info:srw/diagnostic/1/32' => 'Anchoring character in unsupported position', |
|
39
|
|
|
'info:srw/diagnostic/1/33' => 'Combination of proximity/adjacency and masking characters not supported', |
|
40
|
|
|
'info:srw/diagnostic/1/34' => 'Combination of proximity/adjacency and anchoring characters not supported', |
|
41
|
|
|
'info:srw/diagnostic/1/35' => 'Term contains only stopwords', |
|
42
|
|
|
'info:srw/diagnostic/1/36' => 'Term in invalid format for index or relatio', |
|
43
|
|
|
'info:srw/diagnostic/1/37' => 'Unsupported boolean operator', |
|
44
|
|
|
'info:srw/diagnostic/1/38' => 'Too many boolean operators in query', |
|
45
|
|
|
'info:srw/diagnostic/1/39' => 'Proximity not supported', |
|
46
|
|
|
'info:srw/diagnostic/1/40' => 'Unsupported proximity relation', |
|
47
|
|
|
'info:srw/diagnostic/1/41' => 'Unsupported proximity distance', |
|
48
|
|
|
'info:srw/diagnostic/1/42' => 'Unsupported proximity unit', |
|
49
|
|
|
'info:srw/diagnostic/1/43' => 'Unsupported proximity ordering', |
|
50
|
|
|
'info:srw/diagnostic/1/44' => 'Unsupported combination of proximity modifiers', |
|
51
|
|
|
'info:srw/diagnostic/1/46' => 'Unsupported boolean modifier', |
|
52
|
|
|
'info:srw/diagnostic/1/47' => 'Cannot process query; reason unknown', |
|
53
|
|
|
'info:srw/diagnostic/1/48' => 'Query feature unsupported', |
|
54
|
|
|
'info:srw/diagnostic/1/49' => 'Masking character in unsupported position', |
|
55
|
|
|
'info:srw/diagnostic/1/50' => 'Result sets not supported', |
|
56
|
|
|
'info:srw/diagnostic/1/51' => 'Result set does not exist', |
|
57
|
|
|
'info:srw/diagnostic/1/52' => 'Result set temporarily unavailable', |
|
58
|
|
|
'info:srw/diagnostic/1/53' => 'Result sets only supported for retrieval', |
|
59
|
|
|
'info:srw/diagnostic/1/55' => 'Combination of result sets with search terms not supported', |
|
60
|
|
|
'info:srw/diagnostic/1/58' => 'Result set created with unpredictable partial results available', |
|
61
|
|
|
'info:srw/diagnostic/1/59' => 'Result set created with valid partial results available', |
|
62
|
|
|
'info:srw/diagnostic/1/60' => 'Result set not created: too many matching records', |
|
63
|
|
|
'info:srw/diagnostic/1/61' => 'First record position out of range', |
|
64
|
|
|
'info:srw/diagnostic/1/64' => 'Record temporarily unavailable', |
|
65
|
|
|
'info:srw/diagnostic/1/65' => 'Record does not exist', |
|
66
|
|
|
'info:srw/diagnostic/1/66' => 'Unknown schema for retrieval', |
|
67
|
|
|
'info:srw/diagnostic/1/67' => 'Record not available in this schema', |
|
68
|
|
|
'info:srw/diagnostic/1/68' => 'Not authorised to send record', |
|
69
|
|
|
'info:srw/diagnostic/1/69' => 'Not authorised to send record in this schema', |
|
70
|
|
|
'info:srw/diagnostic/1/70' => 'Record too large to send', |
|
71
|
|
|
'info:srw/diagnostic/1/71' => 'Unsupported record packing', |
|
72
|
|
|
'info:srw/diagnostic/1/72' => 'XPath retrieval unsupported', |
|
73
|
|
|
'info:srw/diagnostic/1/73' => 'XPath expression contains unsupported feature', |
|
74
|
|
|
'info:srw/diagnostic/1/74' => 'Unable to evaluate XPath expression', |
|
75
|
|
|
'info:srw/diagnostic/1/80' => 'Sort not supported', |
|
76
|
|
|
'info:srw/diagnostic/1/82' => 'Unsupported sort sequence', |
|
77
|
|
|
'info:srw/diagnostic/1/83' => 'Too many records to sort', |
|
78
|
|
|
'info:srw/diagnostic/1/84' => 'Too many sort keys to sort', |
|
79
|
|
|
'info:srw/diagnostic/1/86' => 'Cannot sort: incompatible record formats', |
|
80
|
|
|
'info:srw/diagnostic/1/87' => 'Unsupported schema for sort', |
|
81
|
|
|
'info:srw/diagnostic/1/88' => 'Unsupported path for sort', |
|
82
|
|
|
'info:srw/diagnostic/1/89' => 'Path unsupported for schema', |
|
83
|
|
|
'info:srw/diagnostic/1/90' => 'Unsupported direction', |
|
84
|
|
|
'info:srw/diagnostic/1/91' => 'Unsupported case', |
|
85
|
|
|
'info:srw/diagnostic/1/92' => 'Unsupported missing value action', |
|
86
|
|
|
'info:srw/diagnostic/1/93' => 'Sort ended due to missing value', |
|
87
|
|
|
'info:srw/diagnostic/1/94' => 'Sort spec included both in query and protocol: query prevails', |
|
88
|
|
|
'info:srw/diagnostic/1/95' => 'Sort spec included both in query and protocol: protocol prevails', |
|
89
|
|
|
'info:srw/diagnostic/1/96' => 'Sort spec included both in query and protocol: error', |
|
90
|
|
|
'info:srw/diagnostic/1/110' => 'Stylesheets not supported', |
|
91
|
|
|
'info:srw/diagnostic/1/120' => 'Response position out of range', |
|
92
|
|
|
'info:srw/diagnostic/1/130' => 'Too many terms matched by masked query term', |
|
93
|
|
|
); |
|
94
|
|
|
|
|
95
|
|
|
/** @var string Raw XML response */ |
|
96
|
|
|
protected $rawResponse = ''; |
|
97
|
|
|
|
|
98
|
|
|
/** @var QuiteSimpleXMLElement XML response */ |
|
99
|
|
|
protected $response; |
|
100
|
|
|
|
|
101
|
|
|
/** @var Client Reference to SRU client object */ |
|
102
|
|
|
protected $client; |
|
103
|
|
|
|
|
104
|
|
|
/** @var string SRU protocol version */ |
|
105
|
|
|
public $version; |
|
106
|
|
|
|
|
107
|
|
|
/** |
|
108
|
|
|
* Create a new response |
|
109
|
|
|
* |
|
110
|
|
|
* @param string $text Raw XML response |
|
111
|
|
|
* @param Client $client SRU client reference (optional) |
|
112
|
|
|
*/ |
|
113
|
|
|
public function __construct($text = null, &$client = null) |
|
114
|
|
|
{ |
|
115
|
|
|
$this->client = $client; |
|
116
|
|
|
|
|
117
|
|
|
if (!is_null($text)) { |
|
118
|
|
|
$this->initializeFromText($text); |
|
119
|
|
|
} |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
protected function initializeFromText($text) |
|
123
|
|
|
{ |
|
124
|
|
|
// Fix missing namespace in Alma records: |
|
125
|
|
|
$text = str_replace('<record xmlns="">', '<record xmlns="http://www.loc.gov/MARC21/slim">', $text); |
|
126
|
|
|
|
|
127
|
|
|
$this->rawResponse = $text; |
|
128
|
|
|
|
|
129
|
|
|
// Throws Danmichaelo\QuiteSimpleXMLElement\InvalidXMLException on invalid xml |
|
130
|
|
|
$this->response = QuiteSimpleXMLElement::make($text, [ |
|
131
|
|
|
'srw' => 'http://www.loc.gov/zing/srw/', |
|
132
|
|
|
'exp' => 'http://explain.z3950.org/dtd/2.0/', |
|
133
|
|
|
'd' => 'http://www.loc.gov/zing/srw/diagnostic/', |
|
134
|
|
|
]); |
|
135
|
|
|
|
|
136
|
|
|
$this->version = $this->response->text('/srw:*/srw:version'); |
|
137
|
|
|
|
|
138
|
|
|
$this->handleDiagnostic($this->response->first('/srw:*/srw:diagnostics/d:diagnostic')); |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
protected function handleDiagnostic(QuiteSimpleXMLElement $node = null) |
|
142
|
|
|
{ |
|
143
|
|
|
if (is_null($node)) { |
|
144
|
|
|
return; |
|
145
|
|
|
} |
|
146
|
|
|
|
|
147
|
|
|
// Only the 'uri' field is required, 'message' and 'details' are optional |
|
148
|
|
|
$uri = $node->text('d:uri'); |
|
149
|
|
|
if (strlen($uri)) { |
|
150
|
|
|
$msg = $node->text('d:message'); |
|
151
|
|
|
$details = $node->text('d:details'); |
|
152
|
|
|
if (empty($msg)) { |
|
153
|
|
|
if (isset(self::$errorMessages[$uri])) { |
|
154
|
|
|
$msg = self::$errorMessages[$uri]; |
|
155
|
|
|
} else { |
|
156
|
|
|
$msg = 'Unknown error'; |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
if (!empty($details)) { |
|
160
|
|
|
$msg .= ' (' . $details . ')'; |
|
161
|
|
|
} |
|
162
|
|
|
throw new Exceptions\SruErrorException($msg, $uri); |
|
163
|
|
|
} |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
/** |
|
167
|
|
|
* Get the raw xml response |
|
168
|
|
|
* |
|
169
|
|
|
* @return string |
|
170
|
|
|
*/ |
|
171
|
|
|
public function asXml() |
|
172
|
|
|
{ |
|
173
|
|
|
return $this->rawResponse; |
|
174
|
|
|
} |
|
175
|
|
|
} |
|
176
|
|
|
|