2828use Illuminate \Database \Eloquent \Builder ;
2929use Illuminate \Database \Eloquent \Model ;
3030use Illuminate \Database \Eloquent \Relations ;
31+ use Illuminate \Database \Eloquent \Scope ;
3132use Illuminate \Support \Collection ;
3233use Neomerx \JsonApi \Contracts \Encoder \Parameters \EncodingParametersInterface ;
3334use Neomerx \JsonApi \Encoder \Parameters \EncodingParameters ;
@@ -86,6 +87,11 @@ abstract class AbstractAdapter extends AbstractResourceAdapter
8687 */
8788 protected $ defaultPagination = null ;
8889
90+ /**
91+ * @var array
92+ */
93+ private $ scopes ;
94+
8995 /**
9096 * Apply the supplied filters to the builder instance.
9197 *
@@ -105,6 +111,7 @@ public function __construct(Model $model, PagingStrategyInterface $paging = null
105111 {
106112 $ this ->model = $ model ;
107113 $ this ->paging = $ paging ;
114+ $ this ->scopes = [];
108115 }
109116
110117 /**
@@ -130,8 +137,12 @@ public function query(EncodingParametersInterface $parameters)
130137 */
131138 public function queryToMany ($ relation , EncodingParametersInterface $ parameters )
132139 {
140+ $ this ->applyScopes (
141+ $ query = $ relation ->newQuery ()
142+ );
143+
133144 return $ this ->queryAllOrOne (
134- $ relation -> newQuery () ,
145+ $ query ,
135146 $ this ->getQueryParameters ($ parameters )
136147 );
137148 }
@@ -148,8 +159,12 @@ public function queryToMany($relation, EncodingParametersInterface $parameters)
148159 */
149160 public function queryToOne ($ relation , EncodingParametersInterface $ parameters )
150161 {
162+ $ this ->applyScopes (
163+ $ query = $ relation ->newQuery ()
164+ );
165+
151166 return $ this ->queryOne (
152- $ relation -> newQuery () ,
167+ $ query ,
153168 $ this ->getQueryParameters ($ parameters )
154169 );
155170 }
@@ -210,6 +225,49 @@ public function findMany(array $resourceIds)
210225 return $ this ->findManyQuery ($ resourceIds )->get ()->all ();
211226 }
212227
228+ /**
229+ * Add scopes.
230+ *
231+ * @param Scope ...$scopes
232+ * @return $this
233+ */
234+ public function addScopes (Scope ...$ scopes ): self
235+ {
236+ foreach ($ scopes as $ scope ) {
237+ $ this ->scopes [get_class ($ scope )] = $ scope ;
238+ }
239+
240+ return $ this ;
241+ }
242+
243+ /**
244+ * Add a global scope using a closure.
245+ *
246+ * @param \Closure $scope
247+ * @param string|null $identifier
248+ * @return $this
249+ */
250+ public function addClosureScope (\Closure $ scope , string $ identifier = null ): self
251+ {
252+ $ identifier = $ identifier ?: spl_object_hash ($ scope );
253+
254+ $ this ->scopes [$ identifier ] = $ scope ;
255+
256+ return $ this ;
257+ }
258+
259+ /**
260+ * @param Builder $query
261+ * @return void
262+ */
263+ protected function applyScopes ($ query ): void
264+ {
265+ /** @var Scope $scope */
266+ foreach ($ this ->scopes as $ identifier => $ scope ) {
267+ $ query ->withGlobalScope ($ identifier , $ scope );
268+ }
269+ }
270+
213271 /**
214272 * Get a new query builder.
215273 *
@@ -220,7 +278,11 @@ public function findMany(array $resourceIds)
220278 */
221279 protected function newQuery ()
222280 {
223- return $ this ->model ->newQuery ();
281+ $ this ->applyScopes (
282+ $ builder = $ this ->model ->newQuery ()
283+ );
284+
285+ return $ builder ;
224286 }
225287
226288 /**
0 commit comments