Skip to content

Conversation

bpolaszek
Copy link
Contributor

@bpolaszek bpolaszek commented Aug 19, 2025

Pull Request

Related issue

Fixes #776

What does this PR do?

  • Add support for the new sort parameter introduced on GET /documents and POST /documents/fetch endpoints in 1.16.
  • The sort parameter is an array by design, but should be imploded when passed through GET, similarly as fields does.
  • It's not DocumentsQuery's responsibility of being aware of what verb will be used for the request. As a consequence, the normalization logic of sort has been introduced in HandlesDocuments, and the way fields was normalized has been refactored accordingly, to maintain things consistent.

FYI: similar normalization issue in #777, there's room for improvement I guess

Summary by CodeRabbit

  • New Features
    • Added multi-field sorting support for document queries.
    • Query parameters now accept list values, serializing arrays as comma-separated values.
  • Bug Fixes
    • Document query output now returns requested fields as an array for consistent formatting.
  • Chores
    • Added PHP 8.1 polyfill dependency to improve compatibility.

Copy link

coderabbitai bot commented Aug 19, 2025

Walkthrough

Adds DocumentsQuery.sort support and setSort(), emits sort in toArray(), changes fields to be emitted as arrays, makes HTTP client serialize list arrays as comma-separated strings, updates endpoint and contract tests for sorting/fields, and adds symfony/polyfill-php81 to composer.json.

Changes

Cohort / File(s) Summary
Documents query API
src/Contracts/DocumentsQuery.php
Adds private sort property (`list
HTTP client query serialization
src/Http/Client.php
buildQueryString() now converts list-like arrays (array_is_list) to comma-separated strings; booleans still become "true"/"false".
Endpoint tests for sorting and fields
tests/Endpoints/DocumentsTest.php
Adds/renames tests to validate sorting behavior and combined filters/fields/sort scenarios; adjusts expected field arrays and assertions.
Contracts tests
tests/Contracts/DocumentsQueryTest.php
Updates expectations: fields in toArray() is returned as an array instead of a comma-separated string.
Dependency update
composer.json
Adds symfony/polyfill-php81 to require.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App as Application
  participant DQ as DocumentsQuery
  participant HC as HttpClient
  participant API as Meilisearch

  App->>DQ: setFields([...])\nsetFilter([...])\nsetSort([...])
  DQ-->>App: toArray() -> { fields, filter, sort }

  App->>HC: GET /indexes/{uid}/documents?{query}
  note right of HC #E8F6EF: buildQueryString()\n- list arrays -> "a,b"\n- booleans -> "true"/"false"
  HC->>API: HTTP request with serialized query
  API-->>HC: JSON documents
  HC-->>App: Response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Update documents methods to accept the sort parameter (#776)
Add new test case (#776)

Out-of-scope changes

Code Change Explanation
Added dependency symfony/polyfill-php81 (composer.json) Not explicitly listed in the issue objectives; likely added to support array_is_list polyfill but the dependency change itself is not requested by the linked issue.

"I nibble code and hop with glee,
Sorts now march in proper key.
Fields are arrays, queries neat,
Tests bound in joyful beat.
A rabbit claps — release is sweet! 🐇"


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 728a792 and 7770c9e.

📒 Files selected for processing (1)
  • src/Http/Client.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Http/Client.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: codecov/patch
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
src/Contracts/DocumentsQuery.php (4)

36-40: Good addition of sort; align phpdoc with returned shape (non-empty) to avoid confusion.

@var list<non-empty-string>|null allows empty lists, while toArray() advertises non-empty-list<string>. Recommend making both consistent and non-empty.

Apply this docblock tweak:

-    /**
-     * @var list<non-empty-string>|null
-     */
+    /**
+     * @var non-empty-list<string>|null
+     */
     private ?array $sort = null;

125-130: Setter looks good; consider guarding against empty/whitespace-only entries.

Optional: reject [] and trim entries to keep the contract tight and avoid sending sort= or invalid values to the API.

-    public function setSort(array $sort): self
-    {
-        $this->sort = $sort;
-
-        return $this;
-    }
+    /**
+     * @param non-empty-list<string> $sort
+     *
+     * @return $this
+     */
+    public function setSort(array $sort): self
+    {
+        // Trim and filter out empty strings to preserve "non-empty" semantics
+        $normalized = array_values(array_filter(array_map(
+            static fn ($s) => \is_string($s) ? trim($s) : $s,
+            $sort
+        ), static fn ($s) => \is_string($s) && $s !== ''));
+
+        // If nothing remains, consider it unset (or throw if you prefer stricter behavior)
+        $this->sort = $normalized !== [] ? $normalized : null;
+
+        return $this;
+    }

145-153: Skip empty arrays for fields/sort to avoid sending empty params (fields= / sort=).

array_filter only removes nulls; empty arrays survive and will be imploded to an empty string in the GET path. Mirror the ids handling by omitting keys when arrays are empty.

     return array_filter([
         'offset' => $this->offset,
         'limit' => $this->limit,
-        'fields' => $this->fields,
+        'fields' => ($this->fields ?? []) !== [] ? $this->fields : null,
         'filter' => $this->filter,
         'retrieveVectors' => (null !== $this->retrieveVectors ? ($this->retrieveVectors ? 'true' : 'false') : null),
         'ids' => ($this->ids ?? []) !== [] ? implode(',', $this->ids) : null,
-        'sort' => $this->sort,
+        'sort' => ($this->sort ?? []) !== [] ? $this->sort : null,
     ], static function ($item) { return null !== $item; });

132-141: Update toArray phpdoc: fields is always an array

The toArray() method only ever emits fields as an array (string normalization happens later in HandlesDocuments). Remove the |non-empty-string union from the docblock.

• File: src/Contracts/DocumentsQuery.php
• Lines: 132–141

     /**
      * @return array{
          offset?: non-negative-int,
          limit?: non-negative-int,
-         fields?: non-empty-list<string>|non-empty-string,
+         fields?: non-empty-list<string>,
          filter?: list<non-empty-string|list<non-empty-string>>,
          retrieveVectors?: 'true'|'false',
          ids?: string,
          sort?: non-empty-list<string>,
      }
      */
tests/Contracts/DocumentsQueryTest.php (1)

23-23: LGTM — test now reflects array-shaped fields in toArray().

Consider adding a small test for setSort() to assert toArray()['sort'] is present and preserves order, e.g. ['genre:desc','id:asc'].

src/Endpoints/Delegates/HandlesDocuments.php (1)

32-37: Normalize only non-empty arrays (avoid fields=/sort= query params).

isset($query['sort'])/isset($query['fields']) is true for empty arrays, leading to implode([])''. Prefer checking non-empty before imploding.

Minimal change:

-                if (isset($query['sort'])) {
-                    $query['sort'] = implode(',', $query['sort']);
-                }
-                if (isset($query['fields'])) {
-                    $query['fields'] = implode(',', $query['fields']);
-                }
+                if (!empty($query['sort'])) {
+                    $query['sort'] = implode(',', $query['sort']);
+                }
+                if (!empty($query['fields'])) {
+                    $query['fields'] = implode(',', $query['fields']);
+                }

Alternatively, to DRY this up:

-                if (!empty($query['sort'])) {
-                    $query['sort'] = implode(',', $query['sort']);
-                }
-                if (!empty($query['fields'])) {
-                    $query['fields'] = implode(',', $query['fields']);
-                }
+                foreach (['sort', 'fields'] as $key) {
+                    if (!empty($query[$key])) {
+                        $query[$key] = implode(',', $query[$key]);
+                    }
+                }
tests/Endpoints/DocumentsTest.php (1)

684-694: LGTM — asserts array-shaped fields when using filter (POST /documents/fetch path).

This guards against accidental GET-style normalization leaking into the POST path. Nice.

Optional: Add a companion test that sets both fields and sort without a filter and asserts the returned documents only include the requested fields and are sorted accordingly, to cover the GET normalization path end-to-end.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5e89737 and 6b6463a.

📒 Files selected for processing (4)
  • src/Contracts/DocumentsQuery.php (2 hunks)
  • src/Endpoints/Delegates/HandlesDocuments.php (1 hunks)
  • tests/Contracts/DocumentsQueryTest.php (1 hunks)
  • tests/Endpoints/DocumentsTest.php (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
tests/Contracts/DocumentsQueryTest.php (1)
src/Contracts/DocumentsQuery.php (1)
  • toArray (143-154)
src/Contracts/DocumentsQuery.php (1)
src/Contracts/SearchQuery.php (2)
  • setSort (297-302)
  • toArray (463-494)
tests/Endpoints/DocumentsTest.php (5)
tests/TestCase.php (2)
  • createEmptyIndex (139-145)
  • safeIndexName (147-150)
src/Endpoints/Delegates/HandlesSettings.php (2)
  • updateSortableAttributes (269-272)
  • updateFilterableAttributes (246-249)
src/Endpoints/Delegates/HandlesDocuments.php (2)
  • addDocuments (47-50)
  • getDocuments (23-45)
src/Endpoints/Delegates/HandlesTasks.php (1)
  • waitForTask (45-48)
src/Contracts/DocumentsQuery.php (5)
  • DocumentsQuery (7-155)
  • setSort (125-130)
  • setFields (70-75)
  • setFilter (84-89)
  • toArray (143-154)

@bpolaszek
Copy link
Contributor Author

CI failure seems unrelated

norkunas
norkunas previously approved these changes Aug 20, 2025
Copy link
Collaborator

@norkunas norkunas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC target branch for this PR should be against bump-meilisearch-v1.16.0

@bpolaszek bpolaszek changed the base branch from main to bump-meilisearch-v1.16.0 August 20, 2025 06:57
@bpolaszek
Copy link
Contributor Author

Sure, just changed that.

@Strift Strift changed the base branch from bump-meilisearch-v1.16.0 to main August 21, 2025 08:02
@Strift Strift dismissed norkunas’s stale review August 21, 2025 08:02

The base branch was changed.

@Strift
Copy link
Collaborator

Strift commented Aug 21, 2025

Hey there,

I reverted the base branch to main as the bump branch is not required anymore (see why below). We can merge after the tests are fixed in #780.

Apologies, updating the base branch dismissed @norkunas's review. I hope we didn't lose useful feedback 😭

A note on bump-** branches

Sorry for the confusion, here's how this repository uses bump-** branches:

The purpose of this branch is to leverage the CI configuration that allows developing and testing features before v1.16 is officially released.

Since 1.16 is now out, PRs implementing v1.16 features can directly target mainbranch.

Thanks, everyone. I also closed #770 to avoid future confusion.

@Strift
Copy link
Collaborator

Strift commented Aug 21, 2025

@coderabbitai review

Copy link

coderabbitai bot commented Aug 21, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Strift Strift requested a review from norkunas August 21, 2025 08:16
@Strift Strift added the enhancement New feature or request label Aug 21, 2025
@bpolaszek bpolaszek requested a review from norkunas August 21, 2025 08:25
norkunas
norkunas previously approved these changes Aug 21, 2025
@bpolaszek
Copy link
Contributor Author

bpolaszek commented Aug 21, 2025

Wait before merging:
As I did in https://github.com/meilisearch/meilisearch-php/pull/777/files#diff-21cc851affdbec541261998beffb80d9f56fca032d0b8563b2430a7a6b5617e7R162
Shouldn't array normalization for GET operations be normalized in buildQueryString instead?

E.g. "for each param as key -> value, if array_is_list(value), then value = implode(',', value) ?"
This would actually apply to fields and sort.

Copy link

codecov bot commented Aug 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.79%. Comparing base (0078a8c) to head (c44c665).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #779      +/-   ##
==========================================
- Coverage   89.78%   87.79%   -2.00%     
==========================================
  Files          59       65       +6     
  Lines        1449     1589     +140     
==========================================
+ Hits         1301     1395      +94     
- Misses        148      194      +46     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/Endpoints/DocumentsTest.php (3)

669-682: Prefer using getResults() over array access on DocumentsResults

Avoid relying on ArrayAccess for DocumentsResults; extract results explicitly for consistency with the rest of this file.

-        $response = $index->getDocuments((new DocumentsQuery())->setSort(['genre:desc', 'id:asc']));
-        self::assertSame(2, $response[0]['id']);
+        $response = $index->getDocuments((new DocumentsQuery())->setSort(['genre:desc', 'id:asc']));
+        $docs = $response->getResults();
+        self::assertSame(2, $docs[0]['id']);

-        $response = $index->getDocuments((new DocumentsQuery())->setSort(['genre:desc', 'id:desc']));
-        self::assertSame(1344, $response[0]['id']);
+        $response = $index->getDocuments((new DocumentsQuery())->setSort(['genre:desc', 'id:desc']));
+        $docs = $response->getResults();
+        self::assertSame(1344, $docs[0]['id']);

Note: I’m intentionally not asking to wait for settings tasks here; per the retrieved learning on this repo, waiting on addDocuments ensures prerequisite settings tasks are completed.


684-699: Use getResults() and make field-order assertion robust

  • Extract results before indexing.
  • Comparing exact key order can be brittle; compare sorted keys to ensure only the requested fields are returned.
-        $response = $index->getDocuments($query);
-        self::assertSame(123, $response[0]['id']);
-        self::assertSame(['id', 'title'], \array_keys($response[0]));
+        $response = $index->getDocuments($query);
+        $docs = $response->getResults();
+        self::assertSame(123, $docs[0]['id']);
+        $keys = \array_keys($docs[0]);
+        sort($keys);
+        self::assertSame(['id', 'title'], $keys);

701-711: Add a complementary GET-path test for fields normalization

A small integration test would ensure arrays are imploded for GET and only requested fields are returned, covering the symmetric case of your POST-path check above.

Proposed test (add near other documents tests):

public function testGetDocumentsWithFieldsArrayOnGet(): void
{
    $index = $this->createEmptyIndex($this->safeIndexName('movies'));
    $promise = $index->addDocuments(self::DOCUMENTS);
    $index->waitForTask($promise['taskUid']);

    $response = $index->getDocuments((new DocumentsQuery())->setFields(['id', 'title']));
    $docs = $response->getResults();
    self::assertNotEmpty($docs);

    // Assert only requested fields are returned (order-independent).
    $keys = \array_keys($docs[0]);
    sort($keys);
    self::assertSame(['id', 'title'], $keys);
}

I can open a follow-up PR with this test if you’d like.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7b6a4f4 and 6e88f69.

📒 Files selected for processing (1)
  • tests/Endpoints/DocumentsTest.php (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T05:05:22.383Z
Learnt from: bpolaszek
PR: meilisearch/meilisearch-php#779
File: tests/Endpoints/DocumentsTest.php:669-682
Timestamp: 2025-08-20T05:05:22.383Z
Learning: In Meilisearch, tasks have implicit dependencies where document operations (like addDocuments) won't be processed until prerequisite setting tasks (like updateSortableAttributes, updateFilterableAttributes) have completed. Therefore, waiting for the addDocuments task completion implicitly ensures that all prerequisite setting tasks have also completed.

Applied to files:

  • tests/Endpoints/DocumentsTest.php
🧬 Code graph analysis (1)
tests/Endpoints/DocumentsTest.php (4)
tests/TestCase.php (2)
  • createEmptyIndex (139-145)
  • safeIndexName (147-150)
src/Endpoints/Delegates/HandlesSettings.php (2)
  • updateSortableAttributes (269-272)
  • updateFilterableAttributes (246-249)
src/Endpoints/Delegates/HandlesDocuments.php (1)
  • getDocuments (23-45)
src/Contracts/DocumentsQuery.php (5)
  • DocumentsQuery (7-158)
  • setSort (128-133)
  • setFields (70-75)
  • setFilter (84-89)
  • toArray (146-157)
🔇 Additional comments (1)
tests/Endpoints/DocumentsTest.php (1)

701-711: LGTM: asserts DocumentsQuery keeps fields as array when filter is set

This validates the contract that DocumentsQuery stays transport-agnostic (arrays in toArray), leaving GET-vs-POST normalization to HandlesDocuments.

@bpolaszek bpolaszek force-pushed the feature/sort-documents branch from 6e88f69 to 67d7c1f Compare August 22, 2025 07:12
@curquiza curquiza changed the title feat: sort documents Support sort for documents endpoint Aug 26, 2025
@curquiza
Copy link
Member

hello @bpolaszek

thank you for your PR

Can you fix the git conflicts with main? Thank you very much for your contribution

@bpolaszek bpolaszek force-pushed the feature/sort-documents branch from ef6de8d to 751c3d0 Compare August 26, 2025 07:54
@bpolaszek
Copy link
Contributor Author

Hi @curquiza,

Here you go!

@bpolaszek bpolaszek requested a review from norkunas August 26, 2025 07:55
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/polyfills.php (1)

19-21: Eliminate unused loop variable ($v) to satisfy PHPMD.

Minor cleanup to avoid “Unused local variable” warnings without allocating extra memory.

Apply this diff:

-        foreach ($array as $k => $v) {
+        foreach ($array as $k => $_) {
src/Http/Client.php (1)

168-170: Consider RFC 3986 encoding for more predictable URLs.

Not required, but using RFC 3986 avoids “+” for spaces and ensures consistent percent-encoding across environments.

Suggested change (outside the selected lines, shown for context):

-        return \count($queryParams) > 0 ? '?'.http_build_query($queryParams) : '';
+        return \count($queryParams) > 0 ? '?'.http_build_query($queryParams, '', '&', PHP_QUERY_RFC3986) : '';
tests/PollyfillsTest.php (3)

11-11: Run the polyfill test on PHP 8.0 too (adjust RequiresPhp).

array_is_list was introduced in PHP 8.1. With < 8.0, you’re skipping 8.0 where the polyfill is also required. Change to < 8.1.

Apply this diff:

-    #[RequiresPhp('< 8.0')]
+    #[RequiresPhp('< 8.1')]

9-9: Typo: rename PollyfillsTest → PolyfillsTest for consistency.

Keeps naming aligned with polyfills.php and common terminology.

If you want, I can propose a follow-up PR commit to rename the file/class.


14-18: Avoid inline PHPStan ignores by bootstrapping Composer in PHPStan.

If you adopt the PHPStan bootstrap suggestion in phpstan.dist.neon, these @phpstan-ignore-line comments become unnecessary.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 67d7c1f and 751c3d0.

📒 Files selected for processing (8)
  • composer.json (1 hunks)
  • phpstan.dist.neon (1 hunks)
  • src/Contracts/DocumentsQuery.php (2 hunks)
  • src/Http/Client.php (1 hunks)
  • src/polyfills.php (1 hunks)
  • tests/Contracts/DocumentsQueryTest.php (1 hunks)
  • tests/Endpoints/DocumentsTest.php (1 hunks)
  • tests/PollyfillsTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/Contracts/DocumentsQueryTest.php
  • tests/Endpoints/DocumentsTest.php
  • src/Contracts/DocumentsQuery.php
🧰 Additional context used
🧬 Code graph analysis (1)
tests/PollyfillsTest.php (2)
tests/TestCase.php (1)
  • TestCase (16-180)
src/polyfills.php (1)
  • array_is_list (11-26)
🪛 PHPMD (2.15.0)
src/polyfills.php

19-19: Avoid unused local variables such as '$v'. (Unused Code Rules)

(UnusedLocalVariable)

🔇 Additional comments (3)
composer.json (1)

31-33: Autoloading the polyfill via "files" is appropriate.

Good choice for globally available helpers while guarding with function_exists in the implementation. No issues spotted.

src/polyfills.php (1)

11-26: Polyfill logic matches PHP 8.1 semantics and is safely guarded.

The implementation is correct, fast, and properly namespaced in the global scope with a function_exists guard. The doc reference to Symfony’s polyfill is a nice touch.

src/Http/Client.php (1)

168-170: List normalization for query params is correct and centralizes GET handling.

Imploding list-like arrays here keeps DocumentsQuery independent of HTTP verb and aligns with Meilisearch’s fields/sort expectations.

@bpolaszek
Copy link
Contributor Author

Failures are related to Meilisearch 1.19 - tests pass on 1.18.

@curquiza
Copy link
Member

@Strift is going to open a PR to fix that soon and be able to merge your PR. Sorry for the incovenience

@bpolaszek
Copy link
Contributor Author

Ty @Strift 👍

@Strift Strift requested a review from norkunas August 28, 2025 09:54
@bpolaszek bpolaszek force-pushed the feature/sort-documents branch from a8b1328 to 09b8b9f Compare August 28, 2025 11:35
@bpolaszek bpolaszek requested a review from norkunas August 28, 2025 11:36
norkunas
norkunas previously approved these changes Aug 28, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
tests/Endpoints/DocumentsTest.php (2)

669-682: Good coverage for GET /documents sorting

This validates sort ordering via GET (no filter), exercising the implode behavior for list-like arrays. Consider, optionally, asserting a few consecutive items or the full order to strengthen the guarantee beyond the first item.


684-699: Make fields-order assertion robust (don’t rely on key order)

JSON/object key order isn’t guaranteed across versions/backends. Sort keys before asserting to avoid brittle failures.

-        self::assertSame(['id', 'title'], array_keys($response[0]));
+        $keys = array_keys($response[0]);
+        sort($keys);
+        self::assertSame(['id', 'title'], $keys);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0d52dea and 09b8b9f.

📒 Files selected for processing (5)
  • composer.json (1 hunks)
  • src/Contracts/DocumentsQuery.php (2 hunks)
  • src/Http/Client.php (1 hunks)
  • tests/Contracts/DocumentsQueryTest.php (1 hunks)
  • tests/Endpoints/DocumentsTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/Http/Client.php
  • tests/Contracts/DocumentsQueryTest.php
  • src/Contracts/DocumentsQuery.php
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T05:05:22.383Z
Learnt from: bpolaszek
PR: meilisearch/meilisearch-php#779
File: tests/Endpoints/DocumentsTest.php:669-682
Timestamp: 2025-08-20T05:05:22.383Z
Learning: In Meilisearch, tasks have implicit dependencies where document operations (like addDocuments) won't be processed until prerequisite setting tasks (like updateSortableAttributes, updateFilterableAttributes) have completed. Therefore, waiting for the addDocuments task completion implicitly ensures that all prerequisite setting tasks have also completed.

Applied to files:

  • tests/Endpoints/DocumentsTest.php
🧬 Code graph analysis (1)
tests/Endpoints/DocumentsTest.php (4)
tests/TestCase.php (2)
  • createEmptyIndex (139-145)
  • safeIndexName (147-150)
src/Endpoints/Delegates/HandlesSettings.php (2)
  • updateSortableAttributes (269-272)
  • updateFilterableAttributes (246-249)
src/Endpoints/Delegates/HandlesDocuments.php (2)
  • addDocuments (41-44)
  • getDocuments (23-39)
src/Contracts/DocumentsQuery.php (5)
  • DocumentsQuery (7-158)
  • setSort (128-133)
  • setFields (70-75)
  • setFilter (84-89)
  • toArray (146-157)
🔇 Additional comments (2)
composer.json (1)

25-26: Polyfill addition for PHP 8.1 features looks appropriate

Including symfony/polyfill-php81 to support array_is_list on PHP 7.4/8.0 aligns with the updated query serialization. No further changes needed here.

tests/Endpoints/DocumentsTest.php (1)

701-711: Fields remain an array in toArray() — LGTM

This ensures DocumentsQuery returns fields as an array (not imploded), matching normalization handled downstream. Looks good.

@bpolaszek
Copy link
Contributor Author

Well, I don't get why linter wants \is_array($value) && array_is_list($value) instead of \is_array($value) && \array_is_list($value), but let's get him happy anyway 🤷

@norkunas
Copy link
Collaborator

It's a limited list which functions can be optimized with prefixing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[v1.16.0] Add support for sorting on the documents API
5 participants