1
|
|
|
<?php namespace Comodojo\Xmlrpc; |
2
|
|
|
|
3
|
|
|
use \Comodojo\Exception\XmlrpcException; |
4
|
|
|
use \XMLWriter; |
5
|
|
|
use \Exception; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* XML-RPC encoder |
9
|
|
|
* |
10
|
|
|
* Main features: |
11
|
|
|
* - support for <nil /> and <ex:nil /> |
12
|
|
|
* - implements true, XML compliant, HTML numeric entities conversion |
13
|
|
|
* - support for CDATA values |
14
|
|
|
* |
15
|
|
|
* @package Comodojo Spare Parts |
16
|
|
|
* @author Marco Giovinazzi <[email protected]> |
17
|
|
|
* @license MIT |
18
|
|
|
* |
19
|
|
|
* LICENSE: |
20
|
|
|
* |
21
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
22
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
23
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
24
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
26
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
27
|
|
|
* THE SOFTWARE. |
28
|
|
|
*/ |
29
|
|
|
|
30
|
|
|
class XmlrpcEncoder { |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Request/Response encoding |
34
|
|
|
* |
35
|
|
|
* @var string |
36
|
|
|
*/ |
37
|
|
|
private $encoding; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* References of special values (base64, datetime, cdata) |
41
|
|
|
* |
42
|
|
|
* @var array |
43
|
|
|
*/ |
44
|
|
|
private $special_types = array(); |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* ex:nil switch (for apache rpc compatibility) |
48
|
|
|
* |
49
|
|
|
* @var bool |
50
|
|
|
*/ |
51
|
|
|
private $use_ex_nil = false; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Constructor method |
55
|
|
|
*/ |
56
|
27 |
|
final public function __construct() { |
57
|
|
|
|
58
|
27 |
|
$this->encoding = defined("XMLRPC_DEFAULT_ENCODING") ? strtolower(XMLRPC_DEFAULT_ENCODING) : 'utf-8'; |
59
|
|
|
|
60
|
27 |
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Set encoding |
64
|
|
|
* |
65
|
|
|
* @param string $encoding |
66
|
|
|
* |
67
|
|
|
* @return \Comodojo\Xmlrpc\XmlrpcEncoder |
68
|
|
|
*/ |
69
|
|
|
final public function setEncoding($encoding) { |
70
|
|
|
|
71
|
|
|
$this->encoding = $encoding; |
72
|
|
|
|
73
|
|
|
return $this; |
74
|
|
|
|
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Get encoding |
79
|
|
|
* |
80
|
|
|
* @return string |
81
|
|
|
*/ |
82
|
|
|
final public function getEncoding() { |
83
|
|
|
|
84
|
|
|
return $this->encoding; |
85
|
|
|
|
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Handle base64 and datetime values |
90
|
|
|
* |
91
|
|
|
* @param mixed $value The referenced value |
92
|
|
|
* @param string $type The type of value |
93
|
|
|
* |
94
|
|
|
* @return \Comodojo\Xmlrpc\XmlrpcEncoder |
95
|
|
|
*/ |
96
|
6 |
|
final public function setValueType(&$value, $type) { |
97
|
|
|
|
98
|
6 |
|
if ( empty($value) || !in_array(strtolower($type), array("base64", "datetime", "cdata")) ) throw new XmlrpcException("Invalid value type"); |
99
|
|
|
|
100
|
6 |
|
$this->special_types[$value] = strtolower($type); |
101
|
|
|
|
102
|
6 |
|
return $this; |
103
|
|
|
|
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Use <ex:nil /> instead of <nil /> (apache xmlrpc compliant) |
108
|
|
|
* |
109
|
|
|
* @param bool $mode |
110
|
|
|
* |
111
|
|
|
* @return \Comodojo\Xmlrpc\XmlrpcEncoder |
112
|
|
|
*/ |
113
|
3 |
|
final public function useExNil($mode = true) { |
114
|
|
|
|
115
|
3 |
|
$this->use_ex_nil = filter_var($mode, FILTER_VALIDATE_BOOLEAN); |
116
|
|
|
|
117
|
3 |
|
return $this; |
118
|
|
|
|
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Encode an xmlrpc response |
123
|
|
|
* |
124
|
|
|
* It expects a scalar, array or NULL as $data and will try to encode it as a valid xmlrpc response. |
125
|
|
|
* |
126
|
|
|
* @param mixed $data |
127
|
|
|
* |
128
|
|
|
* @return string xmlrpc formatted response |
129
|
|
|
* |
130
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
131
|
|
|
* @throws \Exception |
132
|
|
|
*/ |
133
|
6 |
|
public function encodeResponse($data) { |
134
|
|
|
|
135
|
6 |
|
$xml = new XMLWriter(); |
136
|
|
|
|
137
|
6 |
|
$xml->openMemory(); |
138
|
|
|
|
139
|
6 |
|
$xml->setIndent(false); |
140
|
|
|
|
141
|
6 |
|
$xml->startDocument('1.0', $this->encoding); |
142
|
|
|
|
143
|
6 |
|
$xml->startElement("methodResponse"); |
144
|
|
|
|
145
|
6 |
|
$xml->startElement("params"); |
146
|
|
|
|
147
|
6 |
|
$xml->startElement("param"); |
148
|
|
|
|
149
|
6 |
|
$xml->startElement("value"); |
150
|
|
|
|
151
|
|
|
try { |
152
|
|
|
|
153
|
6 |
|
$this->encodeValue($xml, $data); |
154
|
|
|
|
155
|
2 |
|
} catch (XmlrpcException $xe) { |
156
|
|
|
|
157
|
|
|
throw $xe; |
158
|
|
|
|
159
|
|
|
} catch (Exception $e) { |
160
|
|
|
|
161
|
|
|
throw $e; |
162
|
|
|
|
163
|
|
|
} |
164
|
|
|
|
165
|
6 |
|
$xml->endElement(); |
166
|
|
|
|
167
|
6 |
|
$xml->endElement(); |
168
|
|
|
|
169
|
6 |
|
$xml->endElement(); |
170
|
|
|
|
171
|
6 |
|
$xml->endElement(); |
172
|
|
|
|
173
|
6 |
|
$xml->endDocument(); |
174
|
|
|
|
175
|
6 |
|
return trim($xml->outputMemory()); |
176
|
|
|
|
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Encode an xmlrpc call |
181
|
|
|
* |
182
|
|
|
* It expects an array of values as $data and will try to encode it as a valid xmlrpc call. |
183
|
|
|
* |
184
|
|
|
* @param string $method |
185
|
|
|
* @param array $data |
186
|
|
|
* |
187
|
|
|
* @return string xmlrpc formatted call |
188
|
|
|
* |
189
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
190
|
|
|
* @throws \Exception |
191
|
|
|
*/ |
192
|
18 |
|
public function encodeCall($method, $data = array()) { |
193
|
|
|
|
194
|
18 |
|
$xml = new XMLWriter(); |
195
|
|
|
|
196
|
18 |
|
$xml->openMemory(); |
197
|
|
|
|
198
|
18 |
|
$xml->setIndent(false); |
199
|
|
|
|
200
|
18 |
|
$xml->startDocument('1.0', $this->encoding); |
201
|
|
|
|
202
|
18 |
|
$xml->startElement("methodCall"); |
203
|
|
|
|
204
|
18 |
|
$xml->writeElement("methodName", trim($method)); |
205
|
|
|
|
206
|
18 |
|
$xml->startElement("params"); |
207
|
|
|
|
208
|
|
|
try { |
209
|
|
|
|
210
|
18 |
|
foreach ( $data as $d ) { |
211
|
|
|
|
212
|
15 |
|
$xml->startElement("param"); |
213
|
|
|
|
214
|
15 |
|
$xml->startElement("value"); |
215
|
|
|
|
216
|
15 |
|
$this->encodeValue($xml, $d); |
217
|
|
|
|
218
|
15 |
|
$xml->endElement(); |
219
|
|
|
|
220
|
17 |
|
$xml->endElement(); |
221
|
|
|
|
222
|
6 |
|
} |
223
|
|
|
|
224
|
6 |
|
} catch (XmlrpcException $xe) { |
225
|
|
|
|
226
|
|
|
throw $xe; |
227
|
|
|
|
228
|
|
|
} |
229
|
|
|
|
230
|
18 |
|
$xml->endElement(); |
231
|
|
|
|
232
|
18 |
|
$xml->endElement(); |
233
|
|
|
|
234
|
18 |
|
$xml->endDocument(); |
235
|
|
|
|
236
|
18 |
|
return trim($xml->outputMemory()); |
237
|
|
|
|
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Encode an xmlrpc multicall |
242
|
|
|
* |
243
|
|
|
* It expects in input a key->val array where key |
244
|
|
|
* represent the method and val the parameters. |
245
|
|
|
* |
246
|
|
|
* @param array $data |
247
|
|
|
* |
248
|
|
|
* @return string xmlrpc formatted call |
249
|
|
|
* |
250
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
251
|
|
|
* @throws \Exception |
252
|
|
|
*/ |
253
|
6 |
|
public function encodeMulticall($data) { |
254
|
|
|
|
255
|
6 |
|
$packed_requests = array(); |
256
|
|
|
|
257
|
6 |
|
foreach ( $data as $methodName => $params ) { |
258
|
|
|
|
259
|
6 |
|
if ( is_int($methodName) && count($params) == 2 ) { |
260
|
|
|
|
261
|
3 |
|
array_push($packed_requests, array( |
262
|
3 |
|
"methodName" => $params[0], |
263
|
3 |
|
"params" => $params[1] |
264
|
1 |
|
)); |
265
|
|
|
|
266
|
1 |
|
} else { |
267
|
|
|
|
268
|
3 |
|
array_push($packed_requests, array( |
269
|
3 |
|
"methodName" => $methodName, |
270
|
4 |
|
"params" => $params |
271
|
1 |
|
)); |
272
|
|
|
|
273
|
|
|
} |
274
|
|
|
|
275
|
2 |
|
} |
276
|
|
|
|
277
|
6 |
|
return $this->encodeCall("system.multicall", array($packed_requests)); |
278
|
|
|
|
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Encode an xmlrpc error |
283
|
|
|
* |
284
|
|
|
* @param int $error_code |
285
|
|
|
* @param string $error_message |
286
|
|
|
* |
287
|
|
|
* @return string xmlrpc formatted error |
288
|
|
|
*/ |
289
|
3 |
|
public function encodeError($error_code, $error_message) { |
290
|
|
|
|
291
|
3 |
|
$payload = '<?xml version="1.0" encoding="'.$this->encoding.'"?>'; |
292
|
3 |
|
$payload .= "<methodResponse>"; |
293
|
3 |
|
$payload .= $this->encodeFault($error_code, $error_message); |
294
|
3 |
|
$payload .= "</methodResponse>"; |
295
|
|
|
|
296
|
3 |
|
return $payload; |
297
|
|
|
|
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* Encode an xmlrpc fault (without full xml document body) |
302
|
|
|
* |
303
|
|
|
* @param int $error_code |
304
|
|
|
* @param string $error_message |
305
|
|
|
* |
306
|
|
|
* @return string xmlrpc formatted error |
307
|
|
|
*/ |
308
|
3 |
|
private function encodeFault($error_code, $error_message) { |
309
|
|
|
|
310
|
3 |
|
$value = htmlentities($error_message, ENT_QUOTES, $this->encoding, false); |
311
|
|
|
|
312
|
3 |
|
$string = preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]+);/S', 'self::numericEntities', $value); |
313
|
|
|
|
314
|
3 |
|
$payload = "<fault>"; |
315
|
3 |
|
$payload .= "<value>"; |
316
|
3 |
|
$payload .= "<struct>"; |
317
|
3 |
|
$payload .= "<member>"; |
318
|
3 |
|
$payload .= "<name>faultCode</name>"; |
319
|
3 |
|
$payload .= "<value><int>".$error_code."</int></value>"; |
320
|
3 |
|
$payload .= "</member>"; |
321
|
3 |
|
$payload .= "<member>"; |
322
|
3 |
|
$payload .= "<name>faultString</name>"; |
323
|
3 |
|
$payload .= "<value><string>".$string."</string></value>"; |
324
|
3 |
|
$payload .= "</member>"; |
325
|
3 |
|
$payload .= "</struct>"; |
326
|
3 |
|
$payload .= "</value>"; |
327
|
3 |
|
$payload .= "</fault>"; |
328
|
|
|
|
329
|
3 |
|
return $payload; |
330
|
|
|
|
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* Encode a value using XMLWriter object $xml |
335
|
|
|
* |
336
|
|
|
* @param XMLWriter $xml |
337
|
|
|
* @param mixed $value |
338
|
|
|
* |
339
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
340
|
|
|
*/ |
341
|
21 |
|
private function encodeValue(XMLWriter $xml, $value) { |
342
|
|
|
|
343
|
21 |
|
if ( $value === null ) $xml->writeRaw($this->use_ex_nil === true ? '<ex:nil />' : '<nil />'); |
344
|
|
|
|
345
|
21 |
|
else if ( is_array($value) ) { |
346
|
|
|
|
347
|
12 |
|
if ( !self::catchStruct($value) ) $this->encodeArray($xml, $value); |
348
|
|
|
|
349
|
11 |
|
else $this->encodeStruct($xml, $value); |
350
|
|
|
|
351
|
21 |
|
} else if ( @array_key_exists($value, $this->special_types) ) { |
352
|
|
|
|
353
|
6 |
|
switch ( $this->special_types[$value] ) { |
354
|
|
|
|
355
|
6 |
|
case 'base64': |
|
|
|
|
356
|
|
|
|
357
|
3 |
|
$xml->writeElement("base64", $value); |
358
|
|
|
|
359
|
3 |
|
break; |
360
|
|
|
|
361
|
3 |
|
case 'datetime': |
|
|
|
|
362
|
|
|
|
363
|
|
|
$xml->writeElement("dateTime.iso8601", self::timestampToIso8601Time($value)); |
364
|
|
|
|
365
|
|
|
break; |
366
|
|
|
|
367
|
3 |
|
case 'cdata': |
|
|
|
|
368
|
|
|
|
369
|
3 |
|
$xml->writeCData($value); |
370
|
|
|
|
371
|
5 |
|
break; |
372
|
|
|
|
373
|
2 |
|
} |
374
|
|
|
|
375
|
21 |
|
} else if ( is_bool($value) ) { |
376
|
|
|
|
377
|
3 |
|
$xml->writeElement("boolean", $value ? 1 : 0); |
378
|
|
|
|
379
|
21 |
|
} else if ( is_double($value) ) { |
380
|
|
|
|
381
|
|
|
$xml->writeElement("double", $value); |
382
|
|
|
|
383
|
21 |
|
} else if ( is_integer($value) ) { |
384
|
|
|
|
385
|
3 |
|
$xml->writeElement("int", $value); |
386
|
|
|
|
387
|
21 |
|
} else if ( is_object($value) ) { |
388
|
|
|
|
389
|
|
|
$this->encodeObject($xml, $value); |
390
|
|
|
|
391
|
21 |
|
} else if ( is_string($value) ) { |
392
|
|
|
|
393
|
21 |
|
$value = htmlentities($value, ENT_QUOTES, $this->encoding, false); |
394
|
|
|
|
395
|
21 |
|
$string = preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]+);/S', 'self::numericEntities', $value); |
396
|
|
|
|
397
|
21 |
|
$xml->writeRaw("<string>".$string."</string>"); |
398
|
|
|
|
399
|
7 |
|
} else throw new XmlrpcException("Unknown type for encoding"); |
400
|
|
|
|
401
|
21 |
|
} |
402
|
|
|
|
403
|
|
|
/** |
404
|
|
|
* Encode an array using XMLWriter object $xml |
405
|
|
|
* |
406
|
|
|
* @param XMLWriter $xml |
407
|
|
|
* @param mixed $value |
408
|
|
|
*/ |
409
|
12 |
|
private function encodeArray(XMLWriter $xml, $value) { |
410
|
|
|
|
411
|
12 |
|
$xml->startElement("array"); |
412
|
|
|
|
413
|
12 |
|
$xml->startElement("data"); |
414
|
|
|
|
415
|
12 |
|
foreach ( $value as $entry ) { |
416
|
|
|
|
417
|
12 |
|
$xml->startElement("value"); |
418
|
|
|
|
419
|
12 |
|
$this->encodeValue($xml, $entry); |
420
|
|
|
|
421
|
12 |
|
$xml->endElement(); |
422
|
|
|
|
423
|
4 |
|
} |
424
|
|
|
|
425
|
12 |
|
$xml->endElement(); |
426
|
|
|
|
427
|
12 |
|
$xml->endElement(); |
428
|
|
|
|
429
|
12 |
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* Encode an object using XMLWriter object $xml |
433
|
|
|
* |
434
|
|
|
* @param XMLWriter $xml |
435
|
|
|
* @param mixed $value |
436
|
|
|
* |
437
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
438
|
|
|
*/ |
439
|
|
|
private function encodeObject(XMLWriter $xml, $value) { |
440
|
|
|
|
441
|
|
|
if ( $value instanceof \DateTime ) $xml->writeElement("dateTime.iso8601", self::timestampToIso8601Time($value->format('U'))); |
442
|
|
|
|
443
|
|
|
else throw new XmlrpcException("Unknown type for encoding"); |
444
|
|
|
|
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* Encode a struct using XMLWriter object $xml |
449
|
|
|
* |
450
|
|
|
* @param XMLWriter $xml |
451
|
|
|
* @param mixed $value |
452
|
|
|
* |
453
|
|
|
* @throws \Comodojo\Exception\XmlrpcException |
454
|
|
|
*/ |
455
|
9 |
|
private function encodeStruct(XMLWriter $xml, $value) { |
456
|
|
|
|
457
|
9 |
|
$xml->startElement("struct"); |
458
|
|
|
|
459
|
9 |
|
foreach ( $value as $k => $v ) { |
460
|
|
|
|
461
|
9 |
|
$xml->startElement("member"); |
462
|
|
|
|
463
|
9 |
|
$xml->writeElement("name", $k); |
464
|
|
|
|
465
|
9 |
|
$xml->startElement("value"); |
466
|
|
|
|
467
|
9 |
|
$this->encodeValue($xml, $v); |
468
|
|
|
|
469
|
9 |
|
$xml->endElement(); |
470
|
|
|
|
471
|
9 |
|
$xml->endElement(); |
472
|
|
|
|
473
|
3 |
|
} |
474
|
|
|
|
475
|
9 |
|
$xml->endElement(); |
476
|
|
|
|
477
|
9 |
|
} |
478
|
|
|
|
479
|
|
|
/** |
480
|
|
|
* Return true if $value is a struct, false otherwise |
481
|
|
|
* |
482
|
|
|
* @param mixed $value |
483
|
|
|
* |
484
|
|
|
* @return bool |
485
|
|
|
*/ |
486
|
12 |
|
private static function catchStruct($value) { |
487
|
|
|
|
488
|
12 |
|
$values = count($value); |
489
|
|
|
|
490
|
12 |
|
for ( $i = 0; $i < $values; $i++ ) if ( !array_key_exists($i, $value) ) return true; |
491
|
|
|
|
492
|
12 |
|
return false; |
493
|
|
|
|
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
/** |
497
|
|
|
* Convert timestamp to Iso8601 |
498
|
|
|
* |
499
|
|
|
* @param int $timestamp |
500
|
|
|
* |
501
|
|
|
* @return string Iso8601 formatted date |
502
|
|
|
*/ |
503
|
|
|
private static function timestampToIso8601Time($timestamp) { |
504
|
|
|
|
505
|
|
|
return date("Ymd\TH:i:s", $timestamp); |
506
|
|
|
|
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
/** |
510
|
|
|
* Recode named entities into numeric ones |
511
|
|
|
* |
512
|
|
|
* @param mixed $matches |
513
|
|
|
* |
514
|
|
|
* @return string Iso8601 formatted date |
515
|
|
|
*/ |
516
|
|
|
private static function numericEntities($matches) { |
|
|
|
|
517
|
|
|
|
518
|
|
|
static $table = array( |
519
|
|
|
'quot' => '"', 'amp' => '&', 'lt' => '<', 'gt' => '>', 'OElig' => 'Œ', 'oelig' => 'œ', |
520
|
|
|
'Scaron' => 'Š', 'scaron' => 'š', 'Yuml' => 'Ÿ', 'circ' => 'ˆ', 'tilde' => '˜', 'ensp' => ' ', |
521
|
|
|
'emsp' => ' ', 'thinsp' => ' ', 'zwnj' => '‌', 'zwj' => '‍', 'lrm' => '‎', 'rlm' => '‏', |
522
|
|
|
'ndash' => '–', 'mdash' => '—', 'lsquo' => '‘', 'rsquo' => '’', 'sbquo' => '‚', 'ldquo' => '“', |
523
|
|
|
'rdquo' => '”', 'bdquo' => '„', 'dagger' => '†', 'Dagger' => '‡', 'permil' => '‰', 'lsaquo' => '‹', |
524
|
|
|
'rsaquo' => '›', 'euro' => '€', 'fnof' => 'ƒ', 'Alpha' => 'Α', 'Beta' => 'Β', 'Gamma' => 'Γ', |
525
|
|
|
'Delta' => 'Δ', 'Epsilon' => 'Ε', 'Zeta' => 'Ζ', 'Eta' => 'Η', 'Theta' => 'Θ', 'Iota' => 'Ι', |
526
|
|
|
'Kappa' => 'Κ', 'Lambda' => 'Λ', 'Mu' => 'Μ', 'Nu' => 'Ν', 'Xi' => 'Ξ', 'Omicron' => 'Ο', |
527
|
|
|
'Pi' => 'Π', 'Rho' => 'Ρ', 'Sigma' => 'Σ', 'Tau' => 'Τ', 'Upsilon' => 'Υ', 'Phi' => 'Φ', |
528
|
|
|
'Chi' => 'Χ', 'Psi' => 'Ψ', 'Omega' => 'Ω', 'alpha' => 'α', 'beta' => 'β', 'gamma' => 'γ', |
529
|
|
|
'delta' => 'δ', 'epsilon' => 'ε', 'zeta' => 'ζ', 'eta' => 'η', 'theta' => 'θ', 'iota' => 'ι', |
530
|
|
|
'kappa' => 'κ', 'lambda' => 'λ', 'mu' => 'μ', 'nu' => 'ν', 'xi' => 'ξ', 'omicron' => 'ο', |
531
|
|
|
'pi' => 'π', 'rho' => 'ρ', 'sigmaf' => 'ς', 'sigma' => 'σ', 'tau' => 'τ', 'upsilon' => 'υ', |
532
|
|
|
'phi' => 'φ', 'chi' => 'χ', 'psi' => 'ψ', 'omega' => 'ω', 'thetasym' => 'ϑ', 'upsih' => 'ϒ', |
533
|
|
|
'piv' => 'ϖ', 'bull' => '•', 'hellip' => '…', 'prime' => '′', 'Prime' => '″', 'oline' => '‾', |
534
|
|
|
'frasl' => '⁄', 'weierp' => '℘', 'image' => 'ℑ', 'real' => 'ℜ', 'trade' => '™', 'alefsym' => 'ℵ', |
535
|
|
|
'larr' => '←', 'uarr' => '↑', 'rarr' => '→', 'darr' => '↓', 'harr' => '↔', 'crarr' => '↵', |
536
|
|
|
'lArr' => '⇐', 'uArr' => '⇑', 'rArr' => '⇒', 'dArr' => '⇓', 'hArr' => '⇔', 'forall' => '∀', |
537
|
|
|
'part' => '∂', 'exist' => '∃', 'empty' => '∅', 'nabla' => '∇', 'isin' => '∈', 'notin' => '∉', |
538
|
|
|
'ni' => '∋', 'prod' => '∏', 'sum' => '∑', 'minus' => '−', 'lowast' => '∗', 'radic' => '√', |
539
|
|
|
'prop' => '∝', 'infin' => '∞', 'ang' => '∠', 'and' => '∧', 'or' => '∨', 'cap' => '∩', |
540
|
|
|
'cup' => '∪', 'int' => '∫', 'there4' => '∴', 'sim' => '∼', 'cong' => '≅', 'asymp' => '≈', |
541
|
|
|
'ne' => '≠', 'equiv' => '≡', 'le' => '≤', 'ge' => '≥', 'sub' => '⊂', 'sup' => '⊃', |
542
|
|
|
'nsub' => '⊄', 'sube' => '⊆', 'supe' => '⊇', 'oplus' => '⊕', 'otimes' => '⊗', 'perp' => '⊥', |
543
|
|
|
'sdot' => '⋅', 'lceil' => '⌈', 'rceil' => '⌉', 'lfloor' => '⌊', 'rfloor' => '⌋', 'lang' => '〈', |
544
|
|
|
'rang' => '〉', 'loz' => '◊', 'spades' => '♠', 'clubs' => '♣', 'hearts' => '♥', 'diams' => '♦', |
545
|
|
|
'nbsp' => ' ', 'iexcl' => '¡', 'cent' => '¢', 'pound' => '£', 'curren' => '¤', 'yen' => '¥', |
546
|
|
|
'brvbar' => '¦', 'sect' => '§', 'uml' => '¨', 'copy' => '©', 'ordf' => 'ª', 'laquo' => '«', |
547
|
|
|
'not' => '¬', 'shy' => '­', 'reg' => '®', 'macr' => '¯', 'deg' => '°', 'plusmn' => '±', |
548
|
|
|
'sup2' => '²', 'sup3' => '³', 'acute' => '´', 'micro' => 'µ', 'para' => '¶', 'middot' => '·', |
549
|
|
|
'cedil' => '¸', 'sup1' => '¹', 'ordm' => 'º', 'raquo' => '»', 'frac14' => '¼', 'frac12' => '½', |
550
|
|
|
'frac34' => '¾', 'iquest' => '¿', 'Agrave' => 'À', 'Aacute' => 'Á', 'Acirc' => 'Â', 'Atilde' => 'Ã', |
551
|
|
|
'Auml' => 'Ä', 'Aring' => 'Å', 'AElig' => 'Æ', 'Ccedil' => 'Ç', 'Egrave' => 'È', 'Eacute' => 'É', |
552
|
|
|
'Ecirc' => 'Ê', 'Euml' => 'Ë', 'Igrave' => 'Ì', 'Iacute' => 'Í', 'Icirc' => 'Î', 'Iuml' => 'Ï', |
553
|
|
|
'ETH' => 'Ð', 'Ntilde' => 'Ñ', 'Ograve' => 'Ò', 'Oacute' => 'Ó', 'Ocirc' => 'Ô', 'Otilde' => 'Õ', |
554
|
|
|
'Ouml' => 'Ö', 'times' => '×', 'Oslash' => 'Ø', 'Ugrave' => 'Ù', 'Uacute' => 'Ú', 'Ucirc' => 'Û', |
555
|
|
|
'Uuml' => 'Ü', 'Yacute' => 'Ý', 'THORN' => 'Þ', 'szlig' => 'ß', 'agrave' => 'à', 'aacute' => 'á', |
556
|
|
|
'acirc' => 'â', 'atilde' => 'ã', 'auml' => 'ä', 'aring' => 'å', 'aelig' => 'æ', 'ccedil' => 'ç', |
557
|
|
|
'egrave' => 'è', 'eacute' => 'é', 'ecirc' => 'ê', 'euml' => 'ë', 'igrave' => 'ì', 'iacute' => 'í', |
558
|
|
|
'icirc' => 'î', 'iuml' => 'ï', 'eth' => 'ð', 'ntilde' => 'ñ', 'ograve' => 'ò', 'oacute' => 'ó', |
559
|
|
|
'ocirc' => 'ô', 'otilde' => 'õ', 'ouml' => 'ö', 'divide' => '÷', 'oslash' => 'ø', 'ugrave' => 'ù', |
560
|
|
|
'uacute' => 'ú', 'ucirc' => 'û', 'uuml' => 'ü', 'yacute' => 'ý', 'thorn' => 'þ', 'yuml' => 'ÿ' |
561
|
|
|
); |
562
|
|
|
|
563
|
|
|
// cleanup invalid entities |
564
|
|
|
return isset($table[$matches[1]]) ? $table[$matches[1]] : ''; |
565
|
|
|
|
566
|
|
|
} |
567
|
|
|
|
568
|
|
|
} |
569
|
|
|
|
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.