spatie / laravel-query-builder

Easily build Eloquent queries from API requests
https://spatie.be/docs/laravel-query-builder
MIT License
4.06k stars 397 forks source link

Cloning QueryBuilder doesn't actually clone #620

Closed Propaganistas closed 3 years ago

Propaganistas commented 3 years ago

I'm building an index overview with some filter fields and also a discriminating results filter (by means of tabs):

Schermafbeelding 2021-04-08 om 16 17 59

The mentioned count badges should take into account the actual filtered result set, but of course without one filter applied.

So I have this code:

$query = QueryBuilder::for(Workshop::class)
    ->allowedFilters([
        AllowedFilter::scope('search', 'search'),
        AllowedFilter::exact('category', 'category'),
    ])
    ->allowedSorts([
        AllowedSort::field('title', 'title_normalized'),
    ]);

$published_count = $query->clone()->published(true)->count();
$unpublished_count = $query->clone()->published(false)->count();

$workshops = $query->clone()
    ->allowedFilters([
        AllowedFilter::scope('published', 'published'),
    ])
    ->paginate();

I'm first applying the other filters. Then clone the QueryBuilder to get the counts and final result set.

It seems that cloning the query builder doesn't work properly. The internal reference to the underlying Builder is retained and hence the clone() call is a noop.

When dumping the SQL statement of $query between the counts and the final pagination call it seems that those count scopes are both incorporated, even though the $query variable was cloned.