@@ -133,7 +133,17 @@ protected function callScope(callable $scope, array $parameters = []): static
133133 {
134134 array_unshift ($ parameters , $ this );
135135
136- return $ scope (...array_values ($ parameters )) ?? $ this ;
136+ $ result = null ;
137+
138+ $ scopeFilter = $ this ->captureScopeFilters (function () use ($ scope , $ parameters , &$ result ) {
139+ $ result = $ scope (...$ parameters ) ?? $ this ;
140+ });
141+
142+ if ($ scopeFilter ) {
143+ $ this ->query ->addFilter ($ scopeFilter );
144+ }
145+
146+ return $ result ;
137147 }
138148
139149 /**
@@ -477,25 +487,49 @@ public function applyScopes(): static
477487 return $ this ;
478488 }
479489
480- // Scopes should not be escapable, so we will wrap the
481- // application of the scopes within a nested query.
482- $ this ->where (function (self $ query ) {
483- foreach ($ this ->scopes as $ identifier => $ scope ) {
484- if (isset ($ this ->appliedScopes [$ identifier ])) {
485- continue ;
490+ $ builder = clone $ this ;
491+
492+ foreach ($ this ->scopes as $ identifier => $ scope ) {
493+ if (! isset ($ builder ->scopes [$ identifier ])) {
494+ continue ;
495+ }
496+
497+ if (isset ($ builder ->appliedScopes [$ identifier ])) {
498+ continue ;
499+ }
500+
501+ $ builder ->callScope (function (self $ builder ) use ($ scope ) {
502+ if ($ scope instanceof Closure) {
503+ $ scope ($ builder );
486504 }
487505
488506 if ($ scope instanceof Scope) {
489- $ scope ->apply ($ query , $ this ->getModel ());
490- } else {
491- $ scope ($ this );
507+ $ scope ->apply ($ builder , $ this ->getModel ());
492508 }
509+ });
493510
494- $ this ->appliedScopes [$ identifier ] = $ scope ;
495- }
496- });
511+ $ builder ->appliedScopes [$ identifier ] = $ scope ;
512+ }
497513
498- return $ this ;
514+ return $ builder ;
515+ }
516+
517+ /**
518+ * Capture the filters applied while executing the callback.
519+ */
520+ protected function captureScopeFilters (Closure $ callback ): ?Filter
521+ {
522+ $ originalFilter = $ this ->query ->filter ;
523+
524+ $ this ->query ->filter = null ;
525+
526+ try {
527+ $ callback ();
528+
529+ return $ this ->query ->filter ;
530+ } finally {
531+ $ this ->query ->filter = $ originalFilter ;
532+ }
499533 }
500534
501535 /**
0 commit comments