diff --git a/src/Database/Database.php b/src/Database/Database.php index 6fa6797da..52d2b2761 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -372,12 +372,12 @@ class Database protected string $cacheName = 'default'; /** - * @var array + * @var array */ protected static array $filters = []; /** - * @var array + * @var array */ protected array $instanceFilters = []; @@ -471,6 +471,10 @@ public function __construct( ) { $this->adapter = $adapter; $this->cache = $cache; + foreach ($filters as $name => $callbacks) { + $filters[$name]['signature'] = self::computeCallableSignature($callbacks['encode']) + . ':' . self::computeCallableSignature($callbacks['decode']); + } $this->instanceFilters = $filters; $this->setAuthorization(new Authorization()); @@ -8610,6 +8614,7 @@ public static function addFilter(string $name, callable $encode, callable $decod self::$filters[$name] = [ 'encode' => $encode, 'decode' => $decode, + 'signature' => self::computeCallableSignature($encode) . ':' . self::computeCallableSignature($decode), ]; } @@ -9206,9 +9211,39 @@ public function getCacheKeys(string $collectionId, ?string $documentId = null, a if ($documentId) { $documentKey = $documentHashKey = "{$collectionKey}:{$documentId}"; - if (!empty($selects)) { - $documentHashKey = $documentKey . ':' . \md5(\implode($selects)); + $sortedSelects = $selects; + \sort($sortedSelects); + + $filterSignatures = []; + if ($this->filter) { + $disabled = $this->disabledFilters ?? []; + + foreach (self::$filters as $name => $callbacks) { + if (isset($disabled[$name])) { + continue; + } + if (\array_key_exists($name, $this->instanceFilters)) { + continue; + } + $filterSignatures[$name] = $callbacks['signature']; + } + + foreach ($this->instanceFilters as $name => $callbacks) { + if (isset($disabled[$name])) { + continue; + } + $filterSignatures[$name] = $callbacks['signature']; + } + + \ksort($filterSignatures); } + + $payload = \json_encode([ + 'selects' => $sortedSelects, + 'relationships' => $this->resolveRelationships, + 'filters' => $filterSignatures, + ]) ?: ''; + $documentHashKey = $documentKey . ':' . \md5($payload); } return [ @@ -9218,6 +9253,22 @@ public function getCacheKeys(string $collectionId, ?string $documentId = null, a ]; } + private static function computeCallableSignature(callable $callable): string + { + if (\is_string($callable)) { + return $callable; + } + + if (\is_array($callable)) { + $class = \is_object($callable[0]) ? \get_class($callable[0]) : $callable[0]; + return $class . '::' . $callable[1]; + } + + $closure = \Closure::fromCallable($callable); + $ref = new \ReflectionFunction($closure); + return ($ref->getFileName() ?: 'unknown') . ':' . $ref->getStartLine(); + } + /** * @param array $queries * @return void