react-command-bus/src/Context.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;
}
}