Skip to content

Commit 8ab4027

Browse files
committed
build fix for #744
1 parent 03ba82c commit 8ab4027

File tree

2 files changed

+302
-100
lines changed

2 files changed

+302
-100
lines changed

api.include.php

Lines changed: 151 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4525,18 +4525,58 @@ public function read(ServerRequestInterface $request): ResponseInterface
45254525

45264526
class JsonResponder implements Responder
45274527
{
4528+
private $debug;
4529+
4530+
public function __construct(bool $debug)
4531+
{
4532+
$this->debug = $debug;
4533+
}
4534+
45284535
public function error(int $error, string $argument, $details = null): ResponseInterface
45294536
{
4530-
$errorCode = new ErrorCode($error);
4531-
$status = $errorCode->getStatus();
4532-
$document = new ErrorDocument($errorCode, $argument, $details);
4533-
return ResponseFactory::fromObject($status, $document);
4537+
$document = new ErrorDocument(new ErrorCode($error), $argument, $details);
4538+
return ResponseFactory::fromObject($document->getStatus(), $document);
45344539
}
45354540

45364541
public function success($result): ResponseInterface
45374542
{
45384543
return ResponseFactory::fromObject(ResponseFactory::OK, $result);
45394544
}
4545+
4546+
public function exception($exception): ResponseInterface
4547+
{
4548+
$document = ErrorDocument::fromException($exception);
4549+
$response = ResponseFactory::fromObject($document->getStatus(), $document);
4550+
if ($this->debug) {
4551+
$response = ResponseUtils::addExceptionHeaders($response, $exception);
4552+
}
4553+
return $response;
4554+
}
4555+
4556+
public function multi($results): ResponseInterface
4557+
{
4558+
$document = array();
4559+
$success = true;
4560+
foreach ($results as $i=>$result) {
4561+
if ($result instanceof \Throwable) {
4562+
$document[$i] = ErrorDocument::fromException($result);
4563+
$success = false;
4564+
} else {
4565+
$document[$i] = $result;
4566+
}
4567+
}
4568+
$status = $success ? ResponseFactory::OK : ResponseFactory::FAILED_DEPENDENCY;
4569+
$response = ResponseFactory::fromObject($status, $document);
4570+
foreach ($results as $i=>$result) {
4571+
if ($result instanceof \Throwable) {
4572+
if ($this->debug) {
4573+
$response = ResponseUtils::addExceptionHeaders($response, $result);
4574+
}
4575+
}
4576+
}
4577+
return $response;
4578+
}
4579+
45404580
}
45414581
}
45424582

@@ -4614,11 +4654,11 @@ public function read(ServerRequestInterface $request): ResponseInterface
46144654
$params = RequestUtils::getParams($request);
46154655
if (strpos($id, ',') !== false) {
46164656
$ids = explode(',', $id);
4617-
$result = [];
4657+
$argumentLists = array();
46184658
for ($i = 0; $i < count($ids); $i++) {
4619-
array_push($result, $this->service->read($table, $ids[$i], $params));
4659+
$argumentLists[] = array($table, $ids[$i], $params);
46204660
}
4621-
return $this->responder->success($result);
4661+
return $this->responder->multi($this->multiCall([$this->service, 'read'], $argumentLists));
46224662
} else {
46234663
$response = $this->service->read($table, $id, $params);
46244664
if ($response === null) {
@@ -4628,6 +4668,27 @@ public function read(ServerRequestInterface $request): ResponseInterface
46284668
}
46294669
}
46304670

4671+
private function multiCall(callable $method, array $argumentLists): array
4672+
{
4673+
$result = array();
4674+
$success = true;
4675+
$this->service->beginTransaction();
4676+
foreach ($argumentLists as $arguments) {
4677+
try {
4678+
$result[] = call_user_func_array($method, $arguments);
4679+
} catch (\Throwable $e) {
4680+
$success = false;
4681+
$result[] = $e;
4682+
}
4683+
}
4684+
if ($success) {
4685+
$this->service->commitTransaction();
4686+
} else {
4687+
$this->service->rollBackTransaction();
4688+
}
4689+
return $result;
4690+
}
4691+
46314692
public function create(ServerRequestInterface $request): ResponseInterface
46324693
{
46334694
$table = RequestUtils::getPathSegment($request, 2);
@@ -4643,11 +4704,11 @@ public function create(ServerRequestInterface $request): ResponseInterface
46434704
}
46444705
$params = RequestUtils::getParams($request);
46454706
if (is_array($record)) {
4646-
$result = array();
4707+
$argumentLists = array();
46474708
foreach ($record as $r) {
4648-
$result[] = $this->service->create($table, $r, $params);
4709+
$argumentLists[] = array($table, $r, $params);
46494710
}
4650-
return $this->responder->success($result);
4711+
return $this->responder->multi($this->multiCall([$this->service, 'create'], $argumentLists));
46514712
} else {
46524713
return $this->responder->success($this->service->create($table, $record, $params));
46534714
}
@@ -4673,11 +4734,11 @@ public function update(ServerRequestInterface $request): ResponseInterface
46734734
if (count($ids) != count($record)) {
46744735
return $this->responder->error(ErrorCode::ARGUMENT_COUNT_MISMATCH, $id);
46754736
}
4676-
$result = array();
4737+
$argumentLists = array();
46774738
for ($i = 0; $i < count($ids); $i++) {
4678-
$result[] = $this->service->update($table, $ids[$i], $record[$i], $params);
4739+
$argumentLists[] = array($table, $ids[$i], $record[$i], $params);
46794740
}
4680-
return $this->responder->success($result);
4741+
return $this->responder->multi($this->multiCall([$this->service, 'update'], $argumentLists));
46814742
} else {
46824743
if (count($ids) != 1) {
46834744
return $this->responder->error(ErrorCode::ARGUMENT_COUNT_MISMATCH, $id);
@@ -4699,11 +4760,11 @@ public function delete(ServerRequestInterface $request): ResponseInterface
46994760
$params = RequestUtils::getParams($request);
47004761
$ids = explode(',', $id);
47014762
if (count($ids) > 1) {
4702-
$result = array();
4763+
$argumentLists = array();
47034764
for ($i = 0; $i < count($ids); $i++) {
4704-
$result[] = $this->service->delete($table, $ids[$i], $params);
4765+
$argumentLists[] = array($table, $ids[$i], $params);
47054766
}
4706-
return $this->responder->success($result);
4767+
return $this->responder->multi($this->multiCall([$this->service, 'delete'], $argumentLists));
47074768
} else {
47084769
return $this->responder->success($this->service->delete($table, $id, $params));
47094770
}
@@ -4729,11 +4790,11 @@ public function increment(ServerRequestInterface $request): ResponseInterface
47294790
if (count($ids) != count($record)) {
47304791
return $this->responder->error(ErrorCode::ARGUMENT_COUNT_MISMATCH, $id);
47314792
}
4732-
$result = array();
4793+
$argumentLists = array();
47334794
for ($i = 0; $i < count($ids); $i++) {
4734-
$result[] = $this->service->increment($table, $ids[$i], $record[$i], $params);
4795+
$argumentLists[] = array($table, $ids[$i], $record[$i], $params);
47354796
}
4736-
return $this->responder->success($result);
4797+
return $this->responder->multi($this->multiCall([$this->service, 'increment'], $argumentLists));
47374798
} else {
47384799
if (count($ids) != 1) {
47394800
return $this->responder->error(ErrorCode::ARGUMENT_COUNT_MISMATCH, $id);
@@ -5435,6 +5496,21 @@ public function definition(): GenericDefinition
54355496
return $this->definition;
54365497
}
54375498

5499+
public function beginTransaction() /*: void*/
5500+
{
5501+
$this->pdo->beginTransaction();
5502+
}
5503+
5504+
public function commitTransaction() /*: void*/
5505+
{
5506+
$this->pdo->commit();
5507+
}
5508+
5509+
public function rollBackTransaction() /*: void*/
5510+
{
5511+
$this->pdo->rollBack();
5512+
}
5513+
54385514
private function addMiddlewareConditions(string $tableName, Condition $condition): Condition
54395515
{
54405516
$condition1 = VariableStore::get("authorization.conditions.$tableName");
@@ -5609,7 +5685,7 @@ public function getCacheKey(): string
56095685
$this->port,
56105686
$this->database,
56115687
$this->tables,
5612-
$this->username
5688+
$this->username,
56135689
]));
56145690
}
56155691
}
@@ -6979,19 +7055,17 @@ class SimpleRouter implements Router
69797055
private $responder;
69807056
private $cache;
69817057
private $ttl;
6982-
private $debug;
69837058
private $registration;
69847059
private $routes;
69857060
private $routeHandlers;
69867061
private $middlewares;
69877062

6988-
public function __construct(string $basePath, Responder $responder, Cache $cache, int $ttl, bool $debug)
7063+
public function __construct(string $basePath, Responder $responder, Cache $cache, int $ttl)
69897064
{
69907065
$this->basePath = rtrim($this->detectBasePath($basePath), '/');
69917066
$this->responder = $responder;
69927067
$this->cache = $cache;
69937068
$this->ttl = $ttl;
6994-
$this->debug = $debug;
69957069
$this->registration = true;
69967070
$this->routes = $this->loadPathTree();
69977071
$this->routeHandlers = [];
@@ -7102,23 +7176,8 @@ public function handle(ServerRequestInterface $request): ResponseInterface
71027176
}
71037177
try {
71047178
$response = call_user_func($this->routeHandlers[$routeNumbers[0]], $request);
7105-
} catch (\PDOException $e) {
7106-
if (strpos(strtolower($e->getMessage()), 'duplicate') !== false) {
7107-
$response = $this->responder->error(ErrorCode::DUPLICATE_KEY_EXCEPTION, '');
7108-
} elseif (strpos(strtolower($e->getMessage()), 'unique constraint') !== false) {
7109-
$response = $this->responder->error(ErrorCode::DUPLICATE_KEY_EXCEPTION, '');
7110-
} elseif (strpos(strtolower($e->getMessage()), 'default value') !== false) {
7111-
$response = $this->responder->error(ErrorCode::DATA_INTEGRITY_VIOLATION, '');
7112-
} elseif (strpos(strtolower($e->getMessage()), 'allow nulls') !== false) {
7113-
$response = $this->responder->error(ErrorCode::DATA_INTEGRITY_VIOLATION, '');
7114-
} elseif (strpos(strtolower($e->getMessage()), 'constraint') !== false) {
7115-
$response = $this->responder->error(ErrorCode::DATA_INTEGRITY_VIOLATION, '');
7116-
} else {
7117-
$response = $this->responder->error(ErrorCode::ERROR_NOT_FOUND, '');
7118-
}
7119-
if ($this->debug) {
7120-
$response = ResponseUtils::addExceptionHeaders($response, $e);
7121-
}
7179+
} catch (\Throwable $exception) {
7180+
$response = $this->responder->exception($exception);
71227181
}
71237182
return $response;
71247183
}
@@ -9790,32 +9849,37 @@ class SpatialCondition extends ColumnCondition
97909849

97919850
class ErrorDocument implements \JsonSerializable
97929851
{
9793-
public $code;
9794-
public $message;
9852+
public $errorCode;
9853+
public $argument;
97959854
public $details;
97969855

97979856
public function __construct(ErrorCode $errorCode, string $argument, $details)
97989857
{
9799-
$this->code = $errorCode->getCode();
9800-
$this->message = $errorCode->getMessage($argument);
9858+
$this->errorCode = $errorCode;
9859+
$this->argument = $argument;
98019860
$this->details = $details;
98029861
}
98039862

9863+
public function getStatus(): int
9864+
{
9865+
return $this->errorCode->getStatus();
9866+
}
9867+
98049868
public function getCode(): int
98059869
{
9806-
return $this->code;
9870+
return $this->errorCode->getCode();
98079871
}
98089872

98099873
public function getMessage(): string
98109874
{
9811-
return $this->message;
9875+
return $this->errorCode->getMessage($this->argument);
98129876
}
98139877

98149878
public function serialize()
98159879
{
98169880
return [
9817-
'code' => $this->code,
9818-
'message' => $this->message,
9881+
'code' => $this->getCode(),
9882+
'message' => $this->getMessage(),
98199883
'details' => $this->details,
98209884
];
98219885
}
@@ -9824,6 +9888,27 @@ public function jsonSerialize()
98249888
{
98259889
return array_filter($this->serialize());
98269890
}
9891+
9892+
public static function fromException(\Throwable $exception)
9893+
{
9894+
$document = new ErrorDocument(new ErrorCode(ErrorCode::ERROR_NOT_FOUND), $exception->getMessage(), null);
9895+
if ($exception instanceof \PDOException) {
9896+
if (strpos(strtolower($exception->getMessage()), 'duplicate') !== false) {
9897+
$document = new ErrorDocument(new ErrorCode(ErrorCode::DUPLICATE_KEY_EXCEPTION), '', null);
9898+
} elseif (strpos(strtolower($exception->getMessage()), 'unique constraint') !== false) {
9899+
$document = new ErrorDocument(new ErrorCode(ErrorCode::DUPLICATE_KEY_EXCEPTION), '', null);
9900+
} elseif (strpos(strtolower($exception->getMessage()), 'default value') !== false) {
9901+
$document = new ErrorDocument(new ErrorCode(ErrorCode::DATA_INTEGRITY_VIOLATION), '', null);
9902+
} elseif (strpos(strtolower($exception->getMessage()), 'allow nulls') !== false) {
9903+
$document = new ErrorDocument(new ErrorCode(ErrorCode::DATA_INTEGRITY_VIOLATION), '', null);
9904+
} elseif (strpos(strtolower($exception->getMessage()), 'constraint') !== false) {
9905+
$document = new ErrorDocument(new ErrorCode(ErrorCode::DATA_INTEGRITY_VIOLATION), '', null);
9906+
} else {
9907+
$document = new ErrorDocument(new ErrorCode(ErrorCode::ERROR_NOT_FOUND), '', null);
9908+
}
9909+
}
9910+
return $document;
9911+
}
98279912
}
98289913
}
98299914

@@ -10349,6 +10434,21 @@ public function getType(string $table): string
1034910434
return $this->reflection->getType($table);
1035010435
}
1035110436

10437+
public function beginTransaction() /*: void*/
10438+
{
10439+
$this->db->beginTransaction();
10440+
}
10441+
10442+
public function commitTransaction() /*: void*/
10443+
{
10444+
$this->db->commitTransaction();
10445+
}
10446+
10447+
public function rollBackTransaction() /*: void*/
10448+
{
10449+
$this->db->rollBackTransaction();
10450+
}
10451+
1035210452
public function create(string $tableName, /* object */ $record, array $params) /*: ?int*/
1035310453
{
1035410454
$this->sanitizeRecord($tableName, $record, '');
@@ -10773,8 +10873,8 @@ public function __construct(Config $config)
1077310873
$prefix = sprintf('phpcrudapi-%s-', substr(md5(__FILE__), 0, 8));
1077410874
$cache = CacheFactory::create($config->getCacheType(), $prefix, $config->getCachePath());
1077510875
$reflection = new ReflectionService($db, $cache, $config->getCacheTime());
10776-
$responder = new JsonResponder();
10777-
$router = new SimpleRouter($config->getBasePath(), $responder, $cache, $config->getCacheTime(), $config->getDebug());
10876+
$responder = new JsonResponder($config->getDebug());
10877+
$router = new SimpleRouter($config->getBasePath(), $responder, $cache, $config->getCacheTime());
1077810878
foreach ($config->getMiddlewares() as $middleware => $properties) {
1077910879
switch ($middleware) {
1078010880
case 'sslRedirect':
@@ -11297,6 +11397,7 @@ class ResponseFactory
1129711397
const METHOD_NOT_ALLOWED = 405;
1129811398
const CONFLICT = 409;
1129911399
const UNPROCESSABLE_ENTITY = 422;
11400+
const FAILED_DEPENDENCY = 424;
1130011401
const INTERNAL_SERVER_ERROR = 500;
1130111402

1130211403
public static function fromXml(int $status, string $xml): ResponseInterface

0 commit comments

Comments
 (0)