* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT */ class Argument { public function __construct( public mixed $value ) { } /** * Sanitizes argument string into actual * PHP type/object as new Argument instance */ public static function factory(string $argument): static { $argument = trim($argument); // remove grouping parantheses if ( Str::startsWith($argument, '(') && Str::endsWith($argument, ')') ) { $argument = trim(substr($argument, 1, -1)); } // string with single quotes if ( Str::startsWith($argument, "'") && Str::endsWith($argument, "'") ) { $string = substr($argument, 1, -1); $string = str_replace("\'", "'", $string); return new static($string); } // string with double quotes if ( Str::startsWith($argument, '"') && Str::endsWith($argument, '"') ) { $string = substr($argument, 1, -1); $string = str_replace('\"', '"', $string); return new static($string); } // array: split and recursive sanitizing if ( Str::startsWith($argument, '[') && Str::endsWith($argument, ']') ) { $array = substr($argument, 1, -1); $array = Arguments::factory($array); return new static($array); } // numeric if (is_numeric($argument) === true) { if (strpos($argument, '.') === false) { return new static((int)$argument); } return new static((float)$argument); } // Closure if (Str::startsWith($argument, '() =>')) { $query = Str::after($argument, '() =>'); $query = trim($query); return new static(fn () => $query); } return new static(match ($argument) { 'null' => null, 'true' => true, 'false' => false, // resolve parameter for objects and methods itself default => new Query($argument) }); } /** * Return the argument value and * resolves nested objects to scaler types */ public function resolve(array|object $data = []): mixed { // don't resolve the Closure immediately, instead // resolve it to the sub-query and create a new Closure // that resolves the sub-query with the same data set once called if ($this->value instanceof Closure) { $query = ($this->value)(); return fn () => static::factory($query)->resolve($data); } if (is_object($this->value) === true) { return $this->value->resolve($data); } return $this->value; } }