Skip to content

Commit

Permalink
ApiManager: Add native support for aliases. #3
Browse files Browse the repository at this point in the history
  • Loading branch information
janbarasek authored Mar 14, 2020
1 parent 97d3d86 commit d6c1afc
Showing 1 changed file with 73 additions and 37 deletions.
110 changes: 73 additions & 37 deletions src/ApiManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,50 +193,52 @@ private function callActionMethods(BaseEndpoint $endpoint, string $action, strin
{
$endpoint->startup();
$endpoint->startupCheck();
$actionMethod = ($method === 'GET' ? 'action' : strtolower($method)) . Strings::firstUpper($action);
$response = null;

$ref = null;
$args = [];
try {
foreach (($ref = new \ReflectionMethod($endpoint, $actionMethod))->getParameters() as $parameter) {
if (($pName = $parameter->getName()) === 'data') {
if ((($type = $parameter->getType()) !== null && $type->getName() !== 'array') || $type === null) {
RuntimeStructuredApiException::propertyDataMustBeArray($endpoint, $type === null ? null : $type->getName());
}

$args[$pName] = $params;
} elseif (isset($params[$pName]) === true) {
if ($params[$pName]) {
$args[$pName] = $this->fixType($params[$pName], (($type = $parameter->getType()) !== null) ? $type : null);
} elseif (($type = $parameter->getType()) !== null) {
$args[$pName] = $this->returnEmptyValue($endpoint, $pName, $type);
}
} elseif ($parameter->isOptional() === true && $parameter->isDefaultValueAvailable() === true) {
try {
$args[$pName] = $parameter->getDefaultValue();
} catch (\Throwable $e) {
if (($methodName = $this->getActionMethodName($endpoint, $method, $action)) !== null) {
try {
foreach (($ref = new \ReflectionMethod($endpoint, $methodName))->getParameters() as $parameter) {
if (($pName = $parameter->getName()) === 'data') {
if ((($type = $parameter->getType()) !== null && ($typeName = $type->getName()) !== 'array') || $type === null) {
RuntimeStructuredApiException::propertyDataMustBeArray($endpoint, $type === null ? null : $typeName ?? '');
}

$args[$pName] = $params;
} elseif (isset($params[$pName]) === true) {
if ($params[$pName]) {
$args[$pName] = $this->fixType($params[$pName], (($type = $parameter->getType()) !== null) ? $type : null);
} elseif (($type = $parameter->getType()) !== null) {
$args[$pName] = $this->returnEmptyValue($endpoint, $pName, $type);
}
} elseif ($parameter->isOptional() === true && $parameter->isDefaultValueAvailable() === true) {
try {
$args[$pName] = $parameter->getDefaultValue();
} catch (\Throwable $e) {
}
} else {
RuntimeStructuredApiException::parameterDoesNotSet(
$endpoint,
$parameter->getName(),
$parameter->getPosition(),
$methodName ?? ''
);
}
} else {
RuntimeStructuredApiException::parameterDoesNotSet(
$endpoint,
$parameter->getName(),
$parameter->getPosition(),
$actionMethod
);
}
} catch (\ReflectionException $e) {
RuntimeStructuredApiException::reflectionException($e);
}
}

try {
$response = $ref->invokeArgs($endpoint, $args);
} catch (ThrowResponse $e) {
$response = $e->getResponse();
}
try {
$response = $ref !== null ? $ref->invokeArgs($endpoint, $args) : null;
} catch (ThrowResponse $e) {
$response = $e->getResponse();
}

if ($method !== 'GET' && $response === null) {
$response = new JsonResponse(['state' => 'ok']);
}
} catch (\ReflectionException $e) {
RuntimeStructuredApiException::reflectionException($e);
if ($method !== 'GET' && $response === null) {
$response = new JsonResponse(['state' => 'ok']);
}

$endpoint->saveState();
Expand Down Expand Up @@ -316,6 +318,8 @@ private function getBodyParams(string $method): array
*
* 1. If type is nullable, keep original haystack
* 2. Empty value rewrite to null, if null is supported
* 3. Scalar types
* 4. Other -> keep original
*
* @param mixed $haystack
* @param \ReflectionType|null $type
Expand All @@ -332,10 +336,42 @@ private function fixType($haystack, ?\ReflectionType $type)
}

if ($type->getName() === 'bool') {
return \in_array($haystack, ['1', 'true', 'yes'], true) === true;
return \in_array(strtolower((string) $haystack), ['1', 'true', 'yes'], true) === true;
}

if ($type->getName() === 'int') {
return (int) $haystack;
}

if ($type->getName() === 'float') {
return (float) $haystack;
}

return $haystack;
}

/**
* @param BaseEndpoint $endpoint
* @param string $method
* @param string $action
* @return string|null
*/
private function getActionMethodName(BaseEndpoint $endpoint, string $method, string $action): ?string
{
$tryMethods = [];
$tryMethods[] = ($method === 'GET' ? 'action' : strtolower($method)) . Strings::firstUpper($action);
if ($method === 'PUT') {
$tryMethods[] = 'update' . Strings::firstUpper($action);
}

$methodName = null;
foreach ($tryMethods as $tryMethod) {
if (\method_exists($endpoint, $tryMethod) === true) {
return $tryMethod;
}
}

return null;
}

}

0 comments on commit d6c1afc

Please sign in to comment.