@@ -3221,43 +3221,7 @@ public function getDocument(string $collection, string $id, array $queries = [],
32213221
32223222 $ selects = Query::groupByType ($ queries )['selections ' ];
32233223 $ selections = $ this ->validateSelections ($ collection , $ selects );
3224- $ nestedSelections = [];
3225-
3226- foreach ($ queries as $ query ) {
3227- if ($ query ->getMethod () == Query::TYPE_SELECT ) {
3228- $ values = $ query ->getValues ();
3229- foreach ($ values as $ valueIndex => $ value ) {
3230- if (\str_contains ($ value , '. ' )) {
3231- // Shift the top level off the dot-path to pass the selection down the chain
3232- // 'foo.bar.baz' becomes 'bar.baz'
3233- $ nestedSelections [] = Query::select ([
3234- \implode ('. ' , \array_slice (\explode ('. ' , $ value ), 1 ))
3235- ]);
3236-
3237- $ key = \explode ('. ' , $ value )[0 ];
3238-
3239- foreach ($ relationships as $ relationship ) {
3240- if ($ relationship ->getAttribute ('key ' ) === $ key ) {
3241- switch ($ relationship ->getAttribute ('options ' )['relationType ' ]) {
3242- case Database::RELATION_MANY_TO_MANY :
3243- case Database::RELATION_ONE_TO_MANY :
3244- unset($ values [$ valueIndex ]);
3245- break ;
3246-
3247- case Database::RELATION_MANY_TO_ONE :
3248- case Database::RELATION_ONE_TO_ONE :
3249- $ values [$ valueIndex ] = $ key ;
3250- break ;
3251- }
3252- }
3253- }
3254- }
3255- }
3256- $ query ->setValues (\array_values ($ values ));
3257- }
3258- }
3259-
3260- $ queries = \array_values ($ queries );
3224+ $ nestedSelections = $ this ->processRelationshipQueries ($ relationships , $ queries );
32613225
32623226 $ validator = new Authorization (self ::PERMISSION_READ );
32633227 $ documentSecurity = $ collection ->getAttribute ('documentSecurity ' , false );
@@ -6061,50 +6025,7 @@ public function find(string $collection, array $queries = [], string $forPermiss
60616025 );
60626026
60636027 $ selections = $ this ->validateSelections ($ collection , $ selects );
6064- $ nestedSelections = [];
6065-
6066- foreach ($ queries as $ index => &$ query ) {
6067- switch ($ query ->getMethod ()) {
6068- case Query::TYPE_SELECT :
6069- $ values = $ query ->getValues ();
6070- foreach ($ values as $ valueIndex => $ value ) {
6071- if (\str_contains ($ value , '. ' )) {
6072- // Shift the top level off the dot-path to pass the selection down the chain
6073- // 'foo.bar.baz' becomes 'bar.baz'
6074- $ nestedSelections [] = Query::select ([
6075- \implode ('. ' , \array_slice (\explode ('. ' , $ value ), 1 ))
6076- ]);
6077-
6078- $ key = \explode ('. ' , $ value )[0 ];
6079-
6080- foreach ($ relationships as $ relationship ) {
6081- if ($ relationship ->getAttribute ('key ' ) === $ key ) {
6082- switch ($ relationship ->getAttribute ('options ' )['relationType ' ]) {
6083- case Database::RELATION_MANY_TO_MANY :
6084- case Database::RELATION_ONE_TO_MANY :
6085- unset($ values [$ valueIndex ]);
6086- break ;
6087-
6088- case Database::RELATION_MANY_TO_ONE :
6089- case Database::RELATION_ONE_TO_ONE :
6090- $ values [$ valueIndex ] = $ key ;
6091- break ;
6092- }
6093- }
6094- }
6095- }
6096- }
6097- $ query ->setValues (\array_values ($ values ));
6098- break ;
6099- default :
6100- if (\str_contains ($ query ->getAttribute (), '. ' )) {
6101- unset($ queries [$ index ]);
6102- }
6103- break ;
6104- }
6105- }
6106-
6107- $ queries = \array_values ($ queries );
6028+ $ nestedSelections = $ this ->processRelationshipQueries ($ relationships , $ queries );
61086029
61096030 $ getResults = fn () => $ this ->adapter ->find (
61106031 $ collection ->getId (),
@@ -6133,8 +6054,6 @@ public function find(string $collection, array $queries = [], string $forPermiss
61336054 }
61346055 }
61356056
6136- unset($ query );
6137-
61386057 $ this ->trigger (self ::EVENT_DOCUMENT_FIND , $ results );
61396058
61406059 return $ results ;
@@ -6786,7 +6705,7 @@ public function getCacheKeys(string $collectionId, ?string $documentId = null, a
67866705 * @return void
67876706 * @throws QueryException
67886707 */
6789- public function checkQueriesType (array $ queries )
6708+ private function checkQueriesType (array $ queries ): void
67906709 {
67916710 foreach ($ queries as $ query ) {
67926711 if (!$ query instanceof Query) {
@@ -6798,4 +6717,77 @@ public function checkQueriesType(array $queries)
67986717 }
67996718 }
68006719 }
6720+
6721+ /**
6722+ * Process relationship queries, extracting nested selections.
6723+ *
6724+ * @param array<Document> $relationships
6725+ * @param array<Query> $queries
6726+ * @return array<Query>
6727+ */
6728+ private function processRelationshipQueries (
6729+ array $ relationships ,
6730+ array $ queries ,
6731+ ): array {
6732+ $ nestedSelections = [];
6733+
6734+ foreach ($ queries as $ query ) {
6735+ if ($ query ->getMethod () !== Query::TYPE_SELECT ) {
6736+ continue ;
6737+ }
6738+
6739+ $ values = $ query ->getValues ();
6740+ foreach ($ values as $ valueIndex => $ value ) {
6741+ if (!\str_contains ($ value , '. ' )) {
6742+ continue ;
6743+ }
6744+
6745+ $ selectedKey = \explode ('. ' , $ value )[0 ];
6746+
6747+ $ relationship = \array_values (\array_filter (
6748+ $ relationships ,
6749+ fn (Document $ relationship ) => $ relationship ->getAttribute ('key ' ) === $ selectedKey ,
6750+ ))[0 ] ?? null ;
6751+
6752+ if (!$ relationship ) {
6753+ continue ;
6754+ }
6755+
6756+ // Shift the top level off the dot-path to pass the selection down the chain
6757+ // 'foo.bar.baz' becomes 'bar.baz'
6758+ $ nestedSelections [] = Query::select ([
6759+ \implode ('. ' , \array_slice (\explode ('. ' , $ value ), 1 ))
6760+ ]);
6761+
6762+ $ type = $ relationship ->getAttribute ('options ' )['relationType ' ];
6763+ $ side = $ relationship ->getAttribute ('options ' )['side ' ];
6764+
6765+ switch ($ type ) {
6766+ case Database::RELATION_MANY_TO_MANY :
6767+ unset($ values [$ valueIndex ]);
6768+ break ;
6769+ case Database::RELATION_ONE_TO_MANY :
6770+ if ($ side === Database::RELATION_SIDE_PARENT ) {
6771+ unset($ values [$ valueIndex ]);
6772+ } else {
6773+ $ values [$ valueIndex ] = $ selectedKey ;
6774+ }
6775+ break ;
6776+ case Database::RELATION_MANY_TO_ONE :
6777+ if ($ side === Database::RELATION_SIDE_PARENT ) {
6778+ $ values [$ valueIndex ] = $ selectedKey ;
6779+ } else {
6780+ unset($ values [$ valueIndex ]);
6781+ }
6782+ break ;
6783+ case Database::RELATION_ONE_TO_ONE :
6784+ $ values [$ valueIndex ] = $ selectedKey ;
6785+ break ;
6786+ }
6787+ }
6788+ $ query ->setValues (\array_values ($ values ));
6789+ }
6790+
6791+ return $ nestedSelections ;
6792+ }
68016793}
0 commit comments