Response::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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