@@ -8569,11 +8569,13 @@ public function find(string $collection, array $queries = [], string $forPermiss
85698569 *
85708570 * The caller owns authorization context. Use Authorization::skip() around
85718571 * this method for internal reads that should bypass request-user roles.
8572+ * The caller owns invalidation and must purge cached find entries after
8573+ * writes that can change matching documents or returned document payloads.
85728574 *
85738575 * @param string $collection
85748576 * @param array<Query> $queries
85758577 * @param string|null $namespace
8576- * @param array<string> $roles
8578+ * @param array<string> $cacheLabels
85778579 * @param string $forPermission
85788580 * @return array<Document>
85798581 * @throws DatabaseException
@@ -8585,7 +8587,7 @@ public function cachedFind(
85858587 string $ collection ,
85868588 array $ queries = [],
85878589 ?string $ namespace = null ,
8588- array $ roles = [],
8590+ array $ cacheLabels = [],
85898591 string $ forPermission = Database::PERMISSION_READ ,
85908592 ): array {
85918593 foreach ($ queries as $ query ) {
@@ -8605,16 +8607,19 @@ public function cachedFind(
86058607
86068608 $ payload = $ this ->withCache (
86078609 key: $ this ->getFindCacheKey ($ collectionDocument ->getId (), $ namespace ),
8608- callback: function () use ($ collection , $ queries , $ forPermission , &$ cacheMiss , &$ documents ): array {
8610+ callback: function () use ($ collection , $ collectionDocument , $ queries , $ forPermission , &$ cacheMiss , &$ documents ): array {
86098611 $ cacheMiss = true ;
8610- $ documents = $ this ->find ($ collection , $ queries , $ forPermission );
8612+ $ documents = $ this ->filterCachedFindDocuments (
8613+ $ collectionDocument ,
8614+ $ this ->find ($ collection , $ queries , $ forPermission ),
8615+ );
86118616
86128617 return \array_map (
86138618 static fn (Document $ document ): array => $ document ->getArrayCopy (),
86148619 $ documents ,
86158620 );
86168621 },
8617- hash: $ this ->getFindCacheField ($ collectionDocument , $ queries , $ roles , 'documents ' , $ forPermission ),
8622+ hash: $ this ->getFindCacheField ($ collectionDocument , $ queries , $ cacheLabels , 'documents ' , $ forPermission ),
86188623 );
86198624
86208625 if ($ cacheMiss ) {
@@ -8632,42 +8637,32 @@ public function cachedFind(
86328637 throw new AuthorizationException ($ this ->authorization ->getDescription ());
86338638 }
86348639
8635- $ selects = Query::groupByType ($ queries )['selections ' ];
86368640 $ documents = [];
8637-
8638- // A cached list stores candidate IDs. Refresh each candidate so TTL,
8639- // deletion, and permission changes are respected; callers still own
8640- // purging when writes change which documents match the original query.
8641- foreach ($ payload as $ payloadDocument ) {
8642- if (!\is_array ($ payloadDocument )) {
8641+ foreach ($ payload as $ document ) {
8642+ if (!\is_array ($ document )) {
86438643 continue ;
86448644 }
86458645
8646- $ cachedDocument = $ this ->createDocumentInstance ($ collection , $ payloadDocument );
8647- if ($ cachedDocument ->isEmpty ()) {
8648- continue ;
8649- }
8650-
8651- $ document = $ this ->silent (fn () => $ this ->getDocument ($ collection , $ cachedDocument ->getId (), $ selects ));
8652- if ($ document ->isEmpty ()) {
8653- continue ;
8654- }
8655-
8656- if (!$ skipAuth && $ collectionDocument ->getId () !== self ::METADATA ) {
8657- $ permissions = [
8658- ...$ collectionDocument ->getPermissionsByType ($ forPermission ),
8659- ...($ documentSecurity ? $ document ->getPermissionsByType ($ forPermission ) : []),
8660- ];
8661-
8662- if (!$ this ->authorization ->isValid (new Input ($ forPermission , $ permissions ))) {
8663- continue ;
8664- }
8665- }
8646+ $ document = $ this ->createDocumentInstance ($ collection , $ document );
8647+ $ document = $ this ->casting ($ collectionDocument , $ document );
86668648
86678649 $ documents [] = $ document ;
86688650 }
86698651
8670- return $ documents ;
8652+ return $ this ->filterCachedFindDocuments ($ collectionDocument , $ documents );
8653+ }
8654+
8655+ /**
8656+ * @param Document $collection
8657+ * @param array<Document> $documents
8658+ * @return array<Document>
8659+ */
8660+ private function filterCachedFindDocuments (Document $ collection , array $ documents ): array
8661+ {
8662+ return \array_values (\array_filter (
8663+ $ documents ,
8664+ fn (Document $ document ): bool => !$ this ->isTtlExpired ($ collection , $ document ),
8665+ ));
86718666 }
86728667
86738668 /**
@@ -9668,22 +9663,22 @@ public function getFindCacheKey(string $collectionId, ?string $namespace = null)
96689663 *
96699664 * @param Document|null $collection
96709665 * @param array<Query> $queries
9671- * @param array<string> $roles
9666+ * @param array<string> $cacheLabels
96729667 * @param string $field
96739668 * @param string $forPermission
96749669 * @return string
96759670 */
96769671 public function getFindCacheField (
96779672 ?Document $ collection = null ,
96789673 array $ queries = [],
9679- array $ roles = [],
9674+ array $ cacheLabels = [],
96809675 string $ field = 'documents ' ,
96819676 string $ forPermission = self ::PERMISSION_READ ,
96829677 ): string {
96839678 $ this ->checkQueryTypes ($ queries );
96849679
9685- $ roles = \array_values (\array_unique ($ roles ));
9686- \sort ($ roles );
9680+ $ cacheLabels = \array_values (\array_unique ($ cacheLabels ));
9681+ \sort ($ cacheLabels );
96879682
96889683 $ authorizationRoles = \array_values (\array_unique ($ this ->authorization ->getRoles ()));
96899684 \sort ($ authorizationRoles );
@@ -9707,7 +9702,7 @@ public function getFindCacheField(
97079702 return \sprintf (
97089703 '%s:%s:%s:%s ' ,
97099704 $ this ->getFindCacheSchemaHash ($ collection ),
9710- \md5 (\json_encode ($ roles ) ?: '' ),
9705+ \md5 (\json_encode ($ cacheLabels ) ?: '' ),
97119706 \md5 (\json_encode ($ queryPayload ) ?: '' ),
97129707 $ field ,
97139708 );
@@ -9767,6 +9762,8 @@ private function getFindCacheSchemaHash(?Document $collection): string
97679762 return \md5 (
97689763 \json_encode ($ collection ->getAttribute ('attributes ' , []))
97699764 . \json_encode ($ collection ->getAttribute ('indexes ' , []))
9765+ . \json_encode ($ collection ->getAttribute ('$permissions ' , []))
9766+ . \json_encode ($ collection ->getAttribute ('documentSecurity ' , false ))
97709767 );
97719768 }
97729769
0 commit comments