Skip to content

Migrating from spatie/laravel-query-builder ​

Code written for spatie/laravel-query-builder 7.x, 6.x or 5.x needs only the namespace change. The configuration file stays as it is.

Steps ​

  1. Swap the package:

    bash
    composer remove spatie/laravel-query-builder
    composer require myprogs/query-builder
  2. See what is left to change:

    bash
    php artisan query-builder:check-migration

    The command only reads the project. It lists every reference to Spatie\QueryBuilder\ in app, tests, routes, config and database with the file, the line and the class to use instead, and checks that composer.json no longer requires the spatie package. It also warns about what needs a look by hand:

    • installed packages that require spatie/laravel-query-builder themselves: they keep working with the spatie classes, not with this package;
    • keys of the published config/query-builder.php this package does not know;
    • the internal traits (Concerns\*), which behave differently here;
    • what spatie 6 code relies on and the package does not keep (see below);
    • getEloquentBuilder() in classes extending QueryBuilder, AllowedFilter or AllowedSort, and include() in classes extending AllowedInclude (see Differences).

    It exits with 1 while there are references or the spatie package is required, and with 0 otherwise, so it can run in CI. --path=modules --path=src scans other directories instead of the default ones.

  3. Replace the namespace in your code, for example in app/ and tests/:

    bash
    grep -rl 'Spatie\\QueryBuilder' app tests | xargs sed -i '' 's/Spatie\\QueryBuilder/MyProgs\\QueryBuilder/g'

    On Linux drop the '' after -i. Run the check again: it should report no blockers.

  4. Keep your published config/query-builder.php as it is: the file name and every key (parameters, delimiter, filter_value_splitting_enabled, suffixes, disable_invalid_*_query_exception, convert_*) are the same.

  5. If your PHPStan baseline mentions spatie classes, regenerate it: the baseline stores class names escaped (Spatie\\\\QueryBuilder), and the command above does not rewrite it.

Everything that passes the spatie/laravel-query-builder 7.3.6 test suite keeps working. The differences you may notice are listed in Differences from spatie.

From spatie 6.x and older ​

There is no need to upgrade to spatie 7 first. On top of the 7.x API the package accepts:

  • an array instead of a list in allowedFilters([...]), allowedSorts([...]), allowedIncludes([...]), allowedFields([...]), defaultSort([...]) and defaultSorts([...]), with arrays and collections among the items spread one level;
  • custom filters, sorts and includes without the void return type;
  • SortDirection::DESCENDING / SortDirection::ASCENDING and 'desc' / 'asc' in AllowedSort::defaultDirection();
  • AllowedFilter::beginsWithStrict() / endsWithStrict() (the old names of beginsWith() / endsWith());
  • the delimiter as the last argument of the filter factories (AllowedFilter::exact('id', null, true, '|')); it applies to that filter only, as ->delimiter('|') does;
  • the config keys count_suffix, exists_suffix and disable_invalid_includes_query_exception in a published config.

Not kept, and reported by query-builder:check-migration:

  • the static delimiter setters (QueryBuilderRequest::setArrayValueDelimiter() and the like): they are global state; use the delimiter config key;
  • collection methods on the result of an AllowedInclude factory;
  • QueryBuilderRequest::filters() splitting values by the delimiter.

What is not covered ​

  • Packages that type-hint Spatie\QueryBuilder\* classes themselves. They need an adapter or a fork.
  • Code that extends the internal traits of spatie/laravel-query-builder.