composer update
This commit is contained in:
parent
0b3c362c5e
commit
a1f0701630
142 changed files with 4530 additions and 1195 deletions
69
public/kirby/src/Query/Runners/DefaultRunner.php
Normal file
69
public/kirby/src/Query/Runners/DefaultRunner.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Query\Runners;
|
||||
|
||||
use Closure;
|
||||
use Kirby\Query\Parser\Parser;
|
||||
use Kirby\Query\Query;
|
||||
use Kirby\Query\Visitors\DefaultVisitor;
|
||||
|
||||
/**
|
||||
* Runner that caches the AST in memory
|
||||
*
|
||||
* @package Kirby Query
|
||||
* @author Roman Steiner <roman@toastlab.ch>
|
||||
* @link https://getkirby.com
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
* @since 5.1.0
|
||||
* @unstable
|
||||
*/
|
||||
class DefaultRunner extends Runner
|
||||
{
|
||||
/**
|
||||
* Creates a runner for the Query
|
||||
*/
|
||||
public static function for(Query $query): static
|
||||
{
|
||||
return new static(
|
||||
global: $query::$entries,
|
||||
interceptor: $query->intercept(...),
|
||||
cache: $query::$cache
|
||||
);
|
||||
}
|
||||
|
||||
protected function resolver(string $query): Closure
|
||||
{
|
||||
// Load closure from cache
|
||||
if (isset($this->cache[$query]) === true) {
|
||||
return $this->cache[$query];
|
||||
}
|
||||
|
||||
// Parse query as AST
|
||||
$parser = new Parser($query);
|
||||
$ast = $parser->parse();
|
||||
|
||||
// Cache closure to resolve same query
|
||||
return $this->cache[$query] = fn (array $context) => $ast->resolve(
|
||||
new DefaultVisitor($this->global, $context, $this->interceptor)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a query within a given data context
|
||||
*
|
||||
* @param array $context Optional variables to be passed to the query
|
||||
*
|
||||
* @throws \Exception when query is invalid or executor not callable
|
||||
*/
|
||||
public function run(string $query, array $context = []): mixed
|
||||
{
|
||||
// Try resolving query directly from data context or global functions
|
||||
$entry = Scope::get($query, $context, $this->global, false);
|
||||
|
||||
if ($entry !== false) {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
return $this->resolver($query)($context);
|
||||
}
|
||||
}
|
||||
43
public/kirby/src/Query/Runners/Runner.php
Normal file
43
public/kirby/src/Query/Runners/Runner.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Query\Runners;
|
||||
|
||||
use ArrayAccess;
|
||||
use Closure;
|
||||
use Kirby\Query\Query;
|
||||
|
||||
/**
|
||||
* @package Kirby Query
|
||||
* @author Roman Steiner <roman@toastlab.ch>,
|
||||
* Nico Hoffmann <nico@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
* @since 5.1.0
|
||||
* @unstable
|
||||
*/
|
||||
abstract class Runner
|
||||
{
|
||||
/**
|
||||
* @param array $global Allowed global function closures
|
||||
*/
|
||||
public function __construct(
|
||||
public array $global = [],
|
||||
protected Closure|null $interceptor = null,
|
||||
protected ArrayAccess|array &$cache = [],
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a runner instance for the Query
|
||||
*/
|
||||
abstract public static function for(Query $query): static;
|
||||
|
||||
/**
|
||||
* Executes a query within a given data context
|
||||
*
|
||||
* @param array $context Optional variables to be passed to the query
|
||||
*
|
||||
* @throws \Exception when query is invalid or executor not callable
|
||||
*/
|
||||
abstract public function run(string $query, array $context = []): mixed;
|
||||
}
|
||||
94
public/kirby/src/Query/Runners/Scope.php
Normal file
94
public/kirby/src/Query/Runners/Scope.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Query\Runners;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Helper class to execute logic during runtime
|
||||
*
|
||||
* @package Kirby Query
|
||||
* @author Roman Steiner <roman@toastlab.ch>
|
||||
* @link https://getkirby.com
|
||||
* @license https://opensource.org/licenses/MIT
|
||||
* @since 5.1.0
|
||||
* @unstable
|
||||
*/
|
||||
class Scope
|
||||
{
|
||||
/**
|
||||
* Access the key on the object/array during runtime
|
||||
*/
|
||||
public static function access(
|
||||
array|object|null $object,
|
||||
string|int $key,
|
||||
bool $nullSafe = false,
|
||||
...$arguments
|
||||
): mixed {
|
||||
if ($object === null && $nullSafe === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_array($object) === true) {
|
||||
if ($item = $object[$key] ?? $object[(string)$key] ?? null) {
|
||||
if ($arguments) {
|
||||
return $item(...$arguments);
|
||||
}
|
||||
|
||||
if ($item instanceof Closure) {
|
||||
return $item();
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
if (is_object($object) === true) {
|
||||
$key = (string)$key;
|
||||
|
||||
if (
|
||||
method_exists($object, $key) === true ||
|
||||
method_exists($object, '__call') === true
|
||||
) {
|
||||
return $object->$key(...$arguments);
|
||||
}
|
||||
|
||||
return $object->$key ?? null;
|
||||
}
|
||||
|
||||
throw new Exception("Cannot access \"$key\" on " . gettype($object));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a mapping from global context or functions during runtime
|
||||
*/
|
||||
public static function get(
|
||||
string $name,
|
||||
array $context = [],
|
||||
array $global = [],
|
||||
false|null $fallback = null
|
||||
): mixed {
|
||||
// What looks like a variable might actually be a global function
|
||||
// but if there is a variable with the same name,
|
||||
// the variable takes precedence
|
||||
if (isset($context[$name]) === true) {
|
||||
if ($context[$name] instanceof Closure) {
|
||||
return $context[$name]();
|
||||
}
|
||||
|
||||
return $context[$name];
|
||||
}
|
||||
|
||||
if (isset($global[$name]) === true) {
|
||||
return $global[$name]();
|
||||
}
|
||||
|
||||
// Alias to access the global context
|
||||
if ($name === 'this') {
|
||||
return $context;
|
||||
}
|
||||
|
||||
return $fallback;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue