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
|
|
|
|