Skip to content

Commit a56aa81

Browse files
committed
Small improvements to avoid issues
1 parent 0b360c6 commit a56aa81

File tree

4 files changed

+119
-73
lines changed

4 files changed

+119
-73
lines changed

api.php

Lines changed: 108 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6577,7 +6577,8 @@ public function toJdbc(string $type, string $size): string
65776577
$jdbcType = $this->toJdbc['simplified'][$jdbcType];
65786578
}
65796579
if (!isset($this->valid[$jdbcType])) {
6580-
throw new \Exception("Unsupported type '$jdbcType' for driver '$this->driver'");
6580+
//throw new \Exception("Unsupported type '$jdbcType' for driver '$this->driver'");
6581+
$jdbcType = 'clob';
65816582
}
65826583
return $jdbcType;
65836584
}
@@ -8539,91 +8540,131 @@ public function __construct(Router $router, Responder $responder, array $propert
85398540
$this->reflection = $reflection;
85408541
}
85418542

8542-
private function convertFromJsonToXml(string $body): string
8543-
{
8544-
$objectElement = $this->getProperty('objectElement', 'object');
8545-
$prolog = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
8546-
$xml = new \SimpleXMLElement($prolog . '<root></root>');
8547-
$object = json_decode($body);
8548-
if (is_scalar($object)) {
8549-
$xml = $xml->addChild($objectElement, $object);
8550-
} else {
8551-
$xml = $xml->addChild($objectElement);
8552-
$this->convertFromObjectToXml($object, $xml, $objectElement);
8553-
}
8554-
return $prolog . $xml->asXML();
8555-
}
8556-
8557-
private function convertFromObjectToXml($object, $xml, string $objectElement): void
8558-
{
8559-
if (is_array($object)) {
8560-
$xml->addAttribute('type', 'list');
8561-
}
8562-
foreach ($object as $key => $value) {
8563-
if (!is_array($value) && !is_object($value)) {
8564-
if (is_object($object)) {
8565-
$xml->addChild($key, (string) $value);
8543+
private function json2xml($json, $types = 'null,boolean,number,string,object,array')
8544+
{
8545+
$a = json_decode($json);
8546+
$d = new \DOMDocument();
8547+
$c = $d->createElement("root");
8548+
$d->appendChild($c);
8549+
$t = function ($v) {
8550+
$type = gettype($v);
8551+
switch ($type) {
8552+
case 'integer':
8553+
return 'number';
8554+
case 'double':
8555+
return 'number';
8556+
default:
8557+
return strtolower($type);
8558+
}
8559+
};
8560+
$ts = explode(',', $types);
8561+
$f = function ($f, $c, $a, $s = false) use ($t, $d, $ts) {
8562+
if (in_array($t($a), $ts)) {
8563+
$c->setAttribute('type', $t($a));
8564+
}
8565+
if ($t($a) != 'array' && $t($a) != 'object') {
8566+
if ($t($a) == 'boolean') {
8567+
$c->appendChild($d->createTextNode($a ? 'true' : 'false'));
85668568
} else {
8567-
$xml->addChild($objectElement, (string) $value);
8569+
$c->appendChild($d->createTextNode($a));
8570+
}
8571+
} else {
8572+
foreach ($a as $k => $v) {
8573+
if ($k == '__type' && $t($a) == 'object') {
8574+
$c->setAttribute('__type', $v);
8575+
} else {
8576+
if ($t($v) == 'object') {
8577+
$ch = $c->appendChild($d->createElementNS(null, $s ? 'item' : $k));
8578+
$f($f, $ch, $v);
8579+
} else if ($t($v) == 'array') {
8580+
$ch = $c->appendChild($d->createElementNS(null, $s ? 'item' : $k));
8581+
$f($f, $ch, $v, true);
8582+
} else {
8583+
$va = $d->createElementNS(null, $s ? 'item' : $k);
8584+
if ($t($v) == 'boolean') {
8585+
$va->appendChild($d->createTextNode($v ? 'true' : 'false'));
8586+
} else {
8587+
$va->appendChild($d->createTextNode($v));
8588+
}
8589+
$ch = $c->appendChild($va);
8590+
if (in_array($t($v), $ts)) {
8591+
$ch->setAttribute('type', $t($v));
8592+
}
8593+
}
8594+
}
85688595
}
8569-
continue;
8570-
}
8571-
$node = $xml;
8572-
if (is_object($object)) {
8573-
$node = $node->addChild($key);
8574-
} elseif (is_object($value)) {
8575-
$node = $node->addChild($objectElement);
85768596
}
8577-
$this->convertFromObjectToXml($value, $node, $objectElement);
8578-
}
8597+
};
8598+
$f($f, $c, $a, $t($a) == 'array');
8599+
return $d->saveXML($d->documentElement);
85798600
}
85808601

8581-
private function convertFromXmlToJson(string $body)/*: object */
8602+
private function xml2json($xml)
85828603
{
8583-
$objectElement = $this->getProperty('objectElement', 'object');
8584-
$prolog = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
8585-
$xml = new \SimpleXMLElement($prolog . $body);
8586-
$object = $this->convertFromXmlToObject($xml, $objectElement);
8587-
return json_decode(json_encode($object));
8588-
}
8589-
8590-
private function convertFromXmlToObject($xml): array
8591-
{
8592-
$result = [];
8593-
foreach ($xml->children() as $nodeName => $nodeValue) {
8594-
if (count($nodeValue->children()) == 0) {
8595-
$object = strVal($nodeValue);
8596-
} else {
8597-
$object = $this->convertFromXmlToObject($nodeValue);
8598-
}
8599-
$attributes = $xml->attributes();
8600-
if ($attributes['type'] == 'list') {
8601-
$result[] = $object;
8602-
} else {
8603-
$result[$nodeName] = $object;
8604-
}
8604+
$a = @dom_import_simplexml(simplexml_load_string($xml));
8605+
if (!$a) {
8606+
return null;
86058607
}
8606-
return $result;
8608+
$t = function ($v) {
8609+
$t = $v->getAttribute('type');
8610+
$txt = $v->firstChild->nodeType == XML_TEXT_NODE;
8611+
return $t ?: ($txt ? 'string' : 'object');
8612+
};
8613+
$f = function ($f, $a) use ($t) {
8614+
$c = null;
8615+
if ($t($a) == 'null') {
8616+
$c = null;
8617+
} else if ($t($a) == 'boolean') {
8618+
$b = substr(strtolower($a->textContent), 0, 1);
8619+
$c = in_array($b, array('1', 't'));
8620+
} else if ($t($a) == 'number') {
8621+
$c = $a->textContent + 0;
8622+
} else if ($t($a) == 'string') {
8623+
$c = $a->textContent;
8624+
} else if ($t($a) == 'object') {
8625+
$c = array();
8626+
if ($a->getAttribute('__type')) {
8627+
$c['__type'] = $a->getAttribute('__type');
8628+
}
8629+
for ($i = 0; $i < $a->childNodes->length; $i++) {
8630+
$v = $a->childNodes[$i];
8631+
$c[$v->nodeName] = $f($f, $v);
8632+
}
8633+
$c = (object) $c;
8634+
} else if ($t($a) == 'array') {
8635+
$c = array();
8636+
for ($i = 0; $i < $a->childNodes->length; $i++) {
8637+
$v = $a->childNodes[$i];
8638+
$c[$i] = $f($f, $v);
8639+
}
8640+
}
8641+
return $c;
8642+
};
8643+
$c = $f($f, $a);
8644+
return json_encode($c);
86078645
}
86088646

86098647
public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
86108648
{
8611-
$operation = RequestUtils::getOperation($request);
8612-
86138649
parse_str($request->getUri()->getQuery(), $params);
86148650
$isXml = isset($params['format']) && $params['format'] == 'xml';
86158651
if ($isXml) {
86168652
$body = $request->getBody()->getContents();
86178653
if ($body) {
8618-
$json = $this->convertFromXmlToJson($body);
8619-
$request = $request->withParsedBody($json);
8654+
$json = $this->xml2json($body);
8655+
$request = $request->withParsedBody(json_decode($json));
86208656
}
86218657
}
86228658
$response = $next->handle($request);
86238659
if ($isXml) {
86248660
$body = $response->getBody()->getContents();
86258661
if ($body) {
8626-
$xml = $this->convertFromJsonToXml($body);
8662+
$types = implode(',', $this->getArrayProperty('types', 'null,array'));
8663+
if ($types == '' || $types == 'all') {
8664+
$xml = $this->json2xml($body);
8665+
} else {
8666+
$xml = $this->json2xml($body, $types);
8667+
}
86278668
$response = ResponseFactory::fromXml(ResponseFactory::OK, $xml);
86288669
}
86298670
}
@@ -11155,10 +11196,12 @@ public static function toString(ResponseInterface $response): string
1115511196
use Tqdev\PhpCrudApi\ResponseUtils;
1115611197

1115711198
$config = new Config([
11199+
// 'driver' => 'mysql',
11200+
// 'address' => 'localhost',
1115811201
'username' => 'php-crud-api',
1115911202
'password' => 'php-crud-api',
1116011203
'database' => 'php-crud-api',
11161-
'debug' => false
11204+
// d'debug' => false
1116211205
]);
1116311206
$request = RequestFactory::fromGlobals();
1116411207
$api = new Api($config);

src/Tqdev/PhpCrudApi/Database/TypeConverter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ public function toJdbc(string $type, string $size): string
202202
$jdbcType = $this->toJdbc['simplified'][$jdbcType];
203203
}
204204
if (!isset($this->valid[$jdbcType])) {
205-
throw new \Exception("Unsupported type '$jdbcType' for driver '$this->driver'");
205+
//throw new \Exception("Unsupported type '$jdbcType' for driver '$this->driver'");
206+
$jdbcType = 'clob';
206207
}
207208
return $jdbcType;
208209
}

src/index.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
require '../vendor/autoload.php';
1111

1212
$config = new Config([
13+
// 'driver' => 'mysql',
14+
// 'address' => 'localhost',
1315
'username' => 'php-crud-api',
1416
'password' => 'php-crud-api',
1517
'database' => 'php-crud-api',
16-
'debug' => false
18+
// d'debug' => false
1719
]);
1820
$request = RequestFactory::fromGlobals();
1921
$api = new Api($config);

tests/functional/001_records/087_read_and_write_posts_as_xml.log

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,21 @@ Content-Length: 102
1515

1616
<root><id>1</id><user_id>1</user_id><category_id>1</category_id><content>blog started</content></root>
1717
===
18-
GET /records/posts?limit=2
18+
GET /records/posts?size=1
1919
===
2020
200
2121
Content-Type: application/json
22-
Content-Length: 690
22+
Content-Length: 75
2323

24-
{"records":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"},{"id":2,"user_id":1,"category_id":2,"content":"🦀€ Grüßgott, Вiтаю, dobrý deň, hyvää päivää, გამარჯობა, Γεια σας, góðan dag, здравствуйте"},{"id":5,"user_id":1,"category_id":1,"content":"#1"},{"id":6,"user_id":1,"category_id":1,"content":"#2"},{"id":7,"user_id":1,"category_id":1,"content":"#3"},{"id":8,"user_id":1,"category_id":1,"content":"#4"},{"id":9,"user_id":1,"category_id":1,"content":"#5"},{"id":10,"user_id":1,"category_id":1,"content":"#6"},{"id":11,"user_id":1,"category_id":1,"content":"#7"},{"id":12,"user_id":1,"category_id":1,"content":"#8"}]}
24+
{"records":[{"id":1,"user_id":1,"category_id":1,"content":"blog started"}]}
2525
===
26-
GET /records/posts?limit=2&format=xml
26+
GET /records/posts?size=1&format=xml
2727
===
2828
200
2929
Content-Type: text/xml
30-
Content-Length: 1122
30+
Content-Length: 147
3131

32-
<root><records type="array"><item><id>1</id><user_id>1</user_id><category_id>1</category_id><content>blog started</content></item><item><id>2</id><user_id>1</user_id><category_id>2</category_id><content>🦀€ Grüßgott, Вiтаю, dobrý deň, hyvää päivää, გამარჯობა, Γεια σας, góðan dag, здравствуйте</content></item><item><id>5</id><user_id>1</user_id><category_id>1</category_id><content>#1</content></item><item><id>6</id><user_id>1</user_id><category_id>1</category_id><content>#2</content></item><item><id>7</id><user_id>1</user_id><category_id>1</category_id><content>#3</content></item><item><id>8</id><user_id>1</user_id><category_id>1</category_id><content>#4</content></item><item><id>9</id><user_id>1</user_id><category_id>1</category_id><content>#5</content></item><item><id>10</id><user_id>1</user_id><category_id>1</category_id><content>#6</content></item><item><id>11</id><user_id>1</user_id><category_id>1</category_id><content>#7</content></item><item><id>12</id><user_id>1</user_id><category_id>1</category_id><content>#8</content></item></records></root>
32+
<root><records type="array"><item><id>1</id><user_id>1</user_id><category_id>1</category_id><content>blog started</content></item></records></root>
3333
===
3434
GET /records/posts/1?join=users&format=xml
3535
===

0 commit comments

Comments
 (0)