2022-06-17 17:51:59 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Kirby\Toolkit;
|
|
|
|
|
|
|
|
use Closure;
|
|
|
|
use Kirby\Filesystem\F;
|
|
|
|
use ReflectionFunction;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A smart extension of Closures with
|
|
|
|
* magic dependency injection based on the
|
|
|
|
* defined variable names.
|
|
|
|
*
|
|
|
|
* @package Kirby Toolkit
|
|
|
|
* @author Bastian Allgeier <bastian@getkirby.com>
|
|
|
|
* @link https://getkirby.com
|
|
|
|
* @copyright Bastian Allgeier
|
|
|
|
* @license https://opensource.org/licenses/MIT
|
|
|
|
*/
|
|
|
|
class Controller
|
|
|
|
{
|
2023-04-14 16:34:06 +02:00
|
|
|
public function __construct(protected Closure $function)
|
2022-08-31 15:02:43 +02:00
|
|
|
{
|
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
public function arguments(array $data = []): array
|
|
|
|
{
|
|
|
|
$info = new ReflectionFunction($this->function);
|
2024-12-20 12:37:52 +01:00
|
|
|
$args = [];
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2024-12-20 12:37:52 +01:00
|
|
|
foreach ($info->getParameters() as $param) {
|
|
|
|
$name = $param->getName();
|
|
|
|
|
|
|
|
if ($param->isVariadic() === true) {
|
|
|
|
// variadic ... argument collects all remaining values
|
|
|
|
$args += $data;
|
|
|
|
} elseif (isset($data[$name]) === true) {
|
|
|
|
// use provided argument value if available
|
|
|
|
$args[$name] = $data[$name];
|
|
|
|
} elseif ($param->isDefaultValueAvailable() === false) {
|
|
|
|
// use null for any other arguments that don't define
|
|
|
|
// a default value for themselves
|
|
|
|
$args[$name] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $args;
|
2022-08-31 15:02:43 +02:00
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
public function call($bind = null, $data = [])
|
|
|
|
{
|
2025-04-21 18:57:21 +02:00
|
|
|
// unwrap lazy values in arguments
|
2022-08-31 15:02:43 +02:00
|
|
|
$args = $this->arguments($data);
|
2025-04-21 18:57:21 +02:00
|
|
|
$args = LazyValue::unwrap($args);
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
if ($bind === null) {
|
2023-04-14 16:34:06 +02:00
|
|
|
return ($this->function)(...$args);
|
2022-08-31 15:02:43 +02:00
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
return $this->function->call($bind, ...$args);
|
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2024-12-20 12:37:52 +01:00
|
|
|
public static function load(string $file): static|null
|
2022-08-31 15:02:43 +02:00
|
|
|
{
|
|
|
|
if (is_file($file) === false) {
|
|
|
|
return null;
|
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
$function = F::load($file);
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-12-19 14:56:05 +01:00
|
|
|
if ($function instanceof Closure === false) {
|
2022-08-31 15:02:43 +02:00
|
|
|
return null;
|
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
|
2022-08-31 15:02:43 +02:00
|
|
|
return new static($function);
|
|
|
|
}
|
2022-06-17 17:51:59 +02:00
|
|
|
}
|