96 lines
3.1 KiB
PHP
96 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\React\CommandBus;
|
|
|
|
use ReflectionFunction;
|
|
use ReflectionIntersectionType;
|
|
use ReflectionNamedType;
|
|
use ReflectionUnionType;
|
|
|
|
/**
|
|
* The context contains all the data relating to calling a command. It has an
|
|
* unique identifier, the command to call, and the payload data.
|
|
*
|
|
*/
|
|
class Context
|
|
{
|
|
|
|
/** @var string $commandName The command name to call */
|
|
private string $commandName;
|
|
|
|
/** @var array<string,mixed> The payload data */
|
|
private array $payload = [];
|
|
|
|
public function __construct(string $commandName, array $payload)
|
|
{
|
|
$this->commandName = $commandName;
|
|
$this->payload = $payload;
|
|
}
|
|
|
|
public function getCommandName(): string
|
|
{
|
|
return $this->commandName;
|
|
}
|
|
|
|
public function getPayload(): array
|
|
{
|
|
return $this->payload;
|
|
}
|
|
|
|
public function __get($name)
|
|
{
|
|
return $this->payload[$name] ?? null;
|
|
}
|
|
|
|
public function toMethodParameters(callable $callable): array
|
|
{
|
|
$refl = new ReflectionFunction($callable);
|
|
$args = [];
|
|
// Go over the arguments
|
|
foreach ($refl->getParameters() as $parameter) {
|
|
$name = $parameter->getName();
|
|
if (!$parameter->hasType()) {
|
|
// use name
|
|
$args[] = isset($this->payload[$name])
|
|
? $this->payload[$name]
|
|
: ($parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null);
|
|
} else {
|
|
// use name and type
|
|
$type = $parameter->getType();
|
|
if ($type instanceof ReflectionNamedType && $type->isBuiltin()) {
|
|
$typeName = $type->getName();
|
|
$arg = isset($this->payload[$name])
|
|
? $this->payload[$name]
|
|
: ($parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null);
|
|
$args[] = match ($typeName) {
|
|
'string' => strval($arg),
|
|
'boolean' => boolval($arg),
|
|
'array' => (array)$arg,
|
|
'object' => (object)$arg,
|
|
'integer' => intval($arg),
|
|
'float' => floatval($arg),
|
|
default => $arg,
|
|
};
|
|
} elseif ($type instanceof ReflectionNamedType) {
|
|
$typeName = $type->getName();
|
|
switch ($typeName) {
|
|
case Context::class:
|
|
$args[] = $this;
|
|
break;
|
|
default:
|
|
$args[] = null; // FIXME how to handle this?
|
|
}
|
|
|
|
} elseif ($type instanceof ReflectionUnionType) {
|
|
$args[] = null; // FIXME how to handle this?
|
|
} elseif ($type instanceof ReflectionIntersectionType) {
|
|
$args[] = null; // FIXME how to handle this?
|
|
}
|
|
|
|
}
|
|
}
|
|
return $args;
|
|
}
|
|
}
|
|
|