Skip to content
This repository has been archived by the owner on Dec 11, 2022. It is now read-only.

Commit

Permalink
Changed the REST server to JSON encode everything once, instead of JS…
Browse files Browse the repository at this point in the history
…ON in JSON.
  • Loading branch information
hperrin committed Jun 28, 2019
1 parent d027ed4 commit 539ab99
Showing 1 changed file with 64 additions and 46 deletions.
110 changes: 64 additions & 46 deletions src/REST.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,30 @@
* @see http://nymph.io/
*/
class REST {
/**
* Respond to the incoming REST request.
*
* This function will decode the incoming values and call `run`.
*
* @return bool True on success, false on failure.
*/
public function respond() {
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
return $this->run(
$_SERVER['REQUEST_METHOD'],
json_decode($_REQUEST['action'], true),
json_decode($_REQUEST['data'], true)
);
} else {
$args = json_decode(file_get_contents("php://input"), true);
return $this->run(
$_SERVER['REQUEST_METHOD'],
$args['action'],
$args['data']
);
}
}

/**
* Run the Nymph REST server process.
*
Expand All @@ -19,7 +43,7 @@ class REST {
*
* @param string $method The HTTP method.
* @param string $action The Nymph action.
* @param string $data The JSON encoded data.
* @param string $data The decoded data.
* @return bool True on success, false on failure.
*/
public function run($method, $action, $data) {
Expand All @@ -36,13 +60,12 @@ protected function DELETE($action = '', $data = '') {
}
ob_start();
if (in_array($action, ['entity', 'entities'])) {
$ents = json_decode($data, true);
if ($action === 'entity') {
$ents = [$ents];
$data = [$data];
}
$deleted = [];
$failures = false;
foreach ($ents as $delEnt) {
foreach ($data as $delEnt) {
try {
$guid = (int) $delEnt['guid'];
if (Nymph::deleteEntityByID($guid, $delEnt['class'])) {
Expand All @@ -61,7 +84,7 @@ protected function DELETE($action = '', $data = '') {
return $this->httpError(500, 'Internal Server Error');
}
}
header('HTTP/1.1 200 OK', true, 200);
http_response_code(200);
header('Content-Type: application/json');
if ($action === 'entity') {
echo json_encode($deleted[0]);
Expand All @@ -72,7 +95,7 @@ protected function DELETE($action = '', $data = '') {
if (!Nymph::deleteUID("$data")) {
return $this->httpError(500, 'Internal Server Error');
}
header('HTTP/1.1 204 No Content', true, 204);
http_response_code(204);
}
ob_end_flush();
return true;
Expand All @@ -84,14 +107,13 @@ protected function POST($action = '', $data = '') {
}
ob_start();
if (in_array($action, ['entity', 'entities'])) {
$ents = json_decode($data, true);
if ($action === 'entity') {
$ents = [$ents];
$data = [$data];
}
$created = [];
$hadSuccess = false;
$invalidData = false;
foreach ($ents as $entData) {
foreach ($data as $entData) {
if ((int) $entData['guid'] > 0) {
$invalidData = true;
continue;
Expand Down Expand Up @@ -122,58 +144,57 @@ protected function POST($action = '', $data = '') {
return $this->httpError(500, 'Internal Server Error');
}
}
header('HTTP/1.1 201 Created', true, 201);
http_response_code(201);
header('Content-Type: application/json');
if ($action === 'entity') {
echo json_encode($created[0]);
} else {
echo json_encode($created);
}
} elseif ($action === 'method') {
$args = json_decode($data, true);
array_walk($args['params'], [$this, 'referenceToEntity']);
if (isset($args['static']) && $args['static']) {
$className = $args['class'];
array_walk($data['params'], [$this, 'referenceToEntity']);
if (isset($data['static']) && $data['static']) {
$className = $data['class'];
if (!class_exists($className)
|| !isset($className::$clientEnabledStaticMethods)
) {
return $this->httpError(400, 'Bad Request');
}
if (!in_array(
$args['method'],
$data['method'],
$className::$clientEnabledStaticMethods
)
) {
return $this->httpError(403, 'Forbidden');
}
try {
$ret = call_user_func_array(
[$className, $args['method']],
$args['params']
[$className, $data['method']],
$data['params']
);
header('Content-Type: application/json');
echo json_encode(['return' => $ret]);
} catch (\Exception $e) {
return $this->httpError(500, 'Internal Server Error', $e);
}
} else {
$entity = $this->loadEntity($args['entity']);
$entity = $this->loadEntity($data['entity']);
if (!$entity
|| ((int) $args['entity']['guid'] > 0 && !$entity->guid)
|| !is_callable([$entity, $args['method']])
|| ((int) $data['entity']['guid'] > 0 && !$entity->guid)
|| !is_callable([$entity, $data['method']])
) {
return $this->httpError(400, 'Bad Request');
}
if (!in_array($args['method'], $entity->clientEnabledMethods())) {
if (!in_array($data['method'], $entity->clientEnabledMethods())) {
return $this->httpError(403, 'Forbidden');
}
try {
$ret = call_user_func_array(
[$entity, $args['method']],
$args['params']
[$entity, $data['method']],
$data['params']
);
header('Content-Type: application/json');
if ($args['stateless']) {
if ($data['stateless']) {
echo json_encode(['return' => $ret]);
} else {
echo json_encode(['entity' => $entity, 'return' => $ret]);
Expand All @@ -182,7 +203,7 @@ protected function POST($action = '', $data = '') {
return $this->httpError(500, 'Internal Server Error', $e);
}
}
header('HTTP/1.1 200 OK', true, 200);
http_response_code(200);
} else {
try {
$result = Nymph::newUID("$data");
Expand All @@ -192,7 +213,7 @@ protected function POST($action = '', $data = '') {
if (!is_int($result)) {
return $this->httpError(500, 'Internal Server Error');
}
header('HTTP/1.1 201 Created', true, 201);
http_response_code(201);
header('Content-Type: text/plain');
echo $result;
}
Expand All @@ -217,16 +238,15 @@ protected function PATCH($action = '', $data = '') {
protected function doPutOrPatch($action, $data, $patch) {
ob_start();
if ($action === 'uid') {
$args = json_decode($data, true);
if (!isset($args['name'])
|| !isset($args['value'])
|| !is_string($args['name'])
|| !is_numeric($args['value'])
if (!isset($data['name'])
|| !isset($data['value'])
|| !is_string($data['name'])
|| !is_numeric($data['value'])
) {
return $this->httpError(400, 'Bad Request');
}
try {
$result = Nymph::setUID($args['name'], (int) $args['value']);
$result = Nymph::setUID($data['name'], (int) $data['value']);
} catch (\Exception $e) {
return $this->httpError(500, 'Internal Server Error', $e);
}
Expand All @@ -236,16 +256,15 @@ protected function doPutOrPatch($action, $data, $patch) {
header('Content-Type: text/plain');
echo json_encode($result);
} else {
$ents = json_decode($data, true);
if ($action === 'entity') {
$ents = [$ents];
$data = [$data];
}
$saved = [];
$hadSuccess = false;
$invalidData = false;
$notfound = false;
$lastException = null;
foreach ($ents as $entData) {
foreach ($data as $entData) {
if (!is_numeric($entData['guid']) || (int) $entData['guid'] <= 0) {
$invalidData = true;
continue;
Expand Down Expand Up @@ -285,7 +304,7 @@ protected function doPutOrPatch($action, $data, $patch) {
echo json_encode($saved);
}
}
header('HTTP/1.1 200 OK', true, 200);
http_response_code(200);
ob_end_flush();
return true;
}
Expand All @@ -301,30 +320,29 @@ protected function GET($action = '', $data = '') {
];
$method = $actionMap[$action];
if (in_array($action, ['entity', 'entities'])) {
$args = json_decode($data, true);
if (!is_array($args)) {
if (!is_array($data)) {
return $this->httpError(400, 'Bad Request');
}
$count = count($args);
if ($count < 1 || !is_array($args[0])) {
$count = count($data);
if ($count < 1 || !is_array($data[0])) {
return $this->httpError(400, 'Bad Request');
}
if (!isset($args[0]['class']) || !class_exists($args[0]['class'])) {
if (!isset($data[0]['class']) || !class_exists($data[0]['class'])) {
return $this->httpError(400, 'Bad Request');
}
$args[0]['source'] = 'client';
$args[0]['skip_ac'] = false;
$data[0]['source'] = 'client';
$data[0]['skip_ac'] = false;
if ($count > 1) {
for ($i = 1; $i < $count; $i++) {
$newArg = self::translateSelector($args[0]['class'], $args[$i]);
$newArg = self::translateSelector($data[0]['class'], $data[$i]);
if ($newArg === false) {
return $this->httpError(400, 'Bad Request');
}
$args[$i] = $newArg;
$data[$i] = $newArg;
}
}
try {
$result = call_user_func_array("\Nymph\Nymph::$method", $args);
$result = call_user_func_array("\Nymph\Nymph::$method", $data);
} catch (\Exception $e) {
return $this->httpError(500, 'Internal Server Error', $e);
}
Expand Down

0 comments on commit 539ab99

Please sign in to comment.