Upgrade algolia/algoliasearch-client-php to 4.x - #1835
Merged
Conversation
v4 removes initIndex() and the SearchIndex object: every operation is now a method on the client taking the index name. Rather than translate each call site, all contact with the client moves behind App\Search\PackageIndex, so a future client upgrade touches one class and tests stop subclassing vendor code. Search parameters now go in the request body argument rather than the request options. v3 folded unrecognised request options into the body; v4 discards them without complaint, which would have silently dropped filters and pagination. Query::getOptions() is renamed getSearchParams() so the two are not confused. packagist:index --force is disabled. It called $index->clear(), which never existed on the v3 client either, so it has always died before clearing anything. Pointing it at clearObjects() would genuinely empty the live index for the hours a full reindex takes, so that wants doing atomically as its own change. --all still reindexes everything in place. packagist:clean-index now browses with a cursor instead of paging by hand. The old loop drifted every time it deleted a record and could not see past paginationLimitedTo, so it only ever examined the first 300 of the ~557 stale virtual packages. It also checks each record's type before deleting, so it stays safe even if the query's filters were to stop applying. The client is registered lazily because it throws when constructed without credentials. PackageManager depends on it transitively, so every package page would otherwise fail for anyone with no Algolia config; now only search itself degrades, and .env needs no placeholder credentials. saveRecords() rejects records with no objectID, which v3 did client-side. v4's saveObjects() would instead let Algolia generate one, creating a record we could never update or delete again. WebController and PackageManager also catch \InvalidArgumentException, which v4 throws for missing required parameters and for malformed response bodies.
Contributor
composer.lockPackage changes
Settings · Docs · Powered by Private Packagist |
Seldaek
marked this pull request as ready for review
September 7, 2026 08:51
stof
reviewed
Sep 7, 2026
Addresses review feedback on PackageIndex: instead of accepting and returning
bare array<string, mixed>, the interface now declares PackageRecord,
SearchParams, BrowseParams and SearchResponse type aliases, and the two record
producers in IndexPackagesCommand declare PackageRecord as their return type.
objectID is now enforced statically rather than only by the runtime guard in
saveRecords(): dropping it from createSearchableProvider() fails analysis with
"Array does not have offset 'objectID'". The runtime guard stays, since the
interface is also reachable from code phpstan cannot see through.
The shapes are unsealed (...<string, mixed>), because the search API takes far
more parameters than we pass and records gain attributes over time. Search and
browse get separate parameter types: browse takes no query. Search responses
keep their hits loose, as /search.json and clean-index query for different
things and narrow accordingly.
Typing the response also surfaced a lie in the transformer's existing docblock:
it declared hits as array{id: int, meta: array{...}}, but virtual-package hits
carry a string id and no meta at all, as tests/Search/results/search-with-virtual
shows. That went unnoticed because v3's search() returned untyped mixed. The
type is corrected and the meta lookup no longer assumes the key is present.
Contributor
|
The composer.lock diff comment has been updated to reflect new changes in this PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v4 removes initIndex() and the SearchIndex object: every operation is now a method on the client taking the index name. Rather than translate each call site, all contact with the client moves behind App\Search\PackageIndex, so a future client upgrade touches one class and tests stop subclassing vendor code.
Search parameters now go in the request body argument rather than the request options. v3 folded unrecognised request options into the body; v4 discards them without complaint, which would have silently dropped filters and pagination. Query::getOptions() is renamed getSearchParams() so the two are not confused.
packagist:index --force is disabled. It called $index->clear(), which never existed on the v3 client either, so it has always died before clearing anything. Pointing it at clearObjects() would genuinely empty the live index for the hours a full reindex takes, so that wants doing atomically as its own change. --all still reindexes everything in place.
packagist:clean-index now browses with a cursor instead of paging by hand. The old loop drifted every time it deleted a record and could not see past paginationLimitedTo, so it only ever examined the first 300 of the ~557 stale virtual packages. It also checks each record's type before deleting, so it stays safe even if the query's filters were to stop applying.
The client is registered lazily because it throws when constructed without credentials. PackageManager depends on it transitively, so every package page would otherwise fail for anyone with no Algolia config; now only search itself degrades, and .env needs no placeholder credentials.
saveRecords() rejects records with no objectID, which v3 did client-side. v4's saveObjects() would instead let Algolia generate one, creating a record we could never update or delete again.
WebController and PackageManager also catch \InvalidArgumentException, which v4 throws for missing required parameters and for malformed response bodies.