Skip to content

Commit ce932c1

Browse files
committed
Normalize DateTime/Date/Time and add tests for it as in PR #18
1 parent 1539bd1 commit ce932c1

2 files changed

Lines changed: 210 additions & 69 deletions

File tree

src/Api.php

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace atk4\api;
44

5+
use atk4\data\Field;
56
use atk4\data\Model;
67
use Laminas\Diactoros\Request;
78
use Laminas\Diactoros\Response\JsonResponse;
@@ -41,6 +42,12 @@ class Api
4142
/** @var int Response options */
4243
protected $response_options = JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT;
4344

45+
/**
46+
* @var bool If set to true, the first array element of Model->export
47+
* will be returned (GET single record)
48+
* If not, the array will be returned as-is
49+
*/
50+
public $single_record = true;
4451

4552
/**
4653
* Reads everything off globals.
@@ -149,14 +156,45 @@ public function exec($callable, $vars = [])
149156
// if callable function returns agile data model, then export it
150157
// this is important for REST API implementation
151158
if ($ret instanceof Model) {
152-
$ret = $this->exportModel($ret);
159+
160+
$data = [];
161+
162+
$allowed_fields = $this->getAllowedFields($ret, 'read');
163+
if ($this->single_record) {
164+
/** @var Field $field */
165+
foreach($ret->getFields() as $fieldName => $field) {
166+
if(!in_array($fieldName, $allowed_fields)) {
167+
continue;
168+
}
169+
$data[$field->actual ?? $fieldName] = $field->toString();
170+
}
171+
} else {
172+
foreach ($ret as $m) {
173+
/** @var Model $m */
174+
$record = [];
175+
/** @var Field $field */
176+
foreach ($ret->getFields() as $fieldName => $field) {
177+
if(!in_array($fieldName, $allowed_fields)) {
178+
continue;
179+
}
180+
$record[$field->actual ?? $fieldName] = $field->toString();
181+
}
182+
$data[] = $record;
183+
}
184+
}
185+
186+
$ret = $data;
153187
}
154188

155189
// no response, just step out
156190
if ($ret === null) {
157191
return;
158192
}
159193

194+
if ($ret === true) { // manage delete
195+
$ret = [];
196+
}
197+
160198
// emit successful response
161199
$this->successResponse($ret);
162200
}
@@ -194,7 +232,7 @@ protected function call($callable, $vars = [])
194232
*/
195233
protected function exportModel(Model $m)
196234
{
197-
return $m->export($this->getAllowedFields($m, 'read'), null, false);
235+
return $m->export($this->getAllowedFields($m, 'read'), null, true);
198236
}
199237

200238
/**
@@ -242,7 +280,7 @@ protected function loadModelByValue(Model $m, $value)
242280
protected function getAllowedFields(Model $m, $action = 'read')
243281
{
244282
// take model only_fields into account
245-
$fields = is_array($m->only_fields) ? $m->only_fields : [];
283+
$fields = is_array($m->only_fields) && !empty($m->only_fields) ? $m->only_fields : array_keys($m->getFields());
246284

247285
// limit by apiFields
248286
if (isset($m->apiFields, $m->apiFields[$action])) {
@@ -297,7 +335,7 @@ protected function successResponse($response)
297335
// for testing purposes there can be situations when emitter is disabled. then do nothing.
298336
if ($this->emitter) {
299337
$this->emitter->emit($this->response);
300-
exit;
338+
exit; // @todo find a solution to remove this exit.
301339
}
302340

303341
// @todo Should we also stop script execution if no emitter is defined or just ignore that?
@@ -395,6 +433,7 @@ public function rest($pattern, $model = null, $methods = ['read', 'modify', 'del
395433
// GET all records
396434
if (in_array('read', $methods)) {
397435
$f = function (...$params) use ($model) {
436+
$this->single_record = false;
398437
if (is_callable($model)) {
399438
$model = $this->call($model, $params);
400439
}
@@ -413,24 +452,11 @@ public function rest($pattern, $model = null, $methods = ['read', 'modify', 'del
413452
$model = $this->call($model, $params);
414453
}
415454

416-
$this->loadModelByValue($model, $id);
417-
418-
//calculate only once
419-
$allowed_fields = $this->getAllowedFields($model, 'read');
420-
$data = [];
421-
// get all field-elements
422-
foreach ($model->elements as $field => $f) {
423-
//only use allowed fields
424-
if(!in_array($field, $allowed_fields)) {
425-
continue;
426-
}
427-
428-
if ($f instanceof \atk4\data\Field) {
429-
$data[$field] = $f->toString();
430-
}
431-
}
455+
// limit fields
456+
$model->onlyFields($this->getAllowedFields($model, 'read'));
432457

433-
return $data;
458+
// load model and get field values
459+
return $this->loadModelByValue($model, $id);
434460
};
435461

436462
$this->get($pattern.'/:id', $f);
@@ -452,7 +478,7 @@ public function rest($pattern, $model = null, $methods = ['read', 'modify', 'del
452478
$this->loadModelByValue($model, $id)->save($this->request_data);
453479
$model->onlyFields($this->getAllowedFields($model, 'read'));
454480

455-
return $model->get();
481+
return $model;
456482
};
457483
$this->patch($pattern.'/:id', $f);
458484
$this->post($pattern.'/:id', $f);
@@ -472,7 +498,8 @@ public function rest($pattern, $model = null, $methods = ['read', 'modify', 'del
472498
$model->onlyFields($this->getAllowedFields($model, 'read'));
473499

474500
$this->response_code = 201; // http code for created
475-
return $model->get();
501+
502+
return $model;
476503
};
477504
$this->post($pattern, $f);
478505
}

0 commit comments

Comments
 (0)