Skip to content

Conversation

zackkatz
Copy link
Member

@zackkatz zackkatz commented Aug 22, 2025

Summary

  • Fixes Result Number (sequence) field always starting at 0 instead of using the configured "Start Number" value
  • Bug only affected field display in Views - merge tags worked correctly
  • Adds comprehensive test coverage for all sequence field scenarios

What Changed

  • Modified get_sequence() method to read field configuration from View settings
  • Refactored code into smaller, testable methods for better maintainability
  • Added proper handling for single entry views with filters and custom sort orders
  • Consolidated all sequence field tests into a single comprehensive test file

Test Plan

@Mwalek Please let me know if you have any questions.

  • Test Result Number field with custom Start Number in View
  • Test with pagination and different page sizes
  • Test with different default sort orders in a View
  • Test reverse sequence mode with custom start values
  • Test field in Single Entry on Views that have Advanced Filters configured (in order to make sure that this works for not just simple, ordered results)
  • Test that the {sequence} merge tags continue to work correctly

Fixes #2431

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • More reliable numbering for the Result Number (Sequence) field across list, paginated, and single-entry views; reduced memory usage for single-entry positioning.
  • Bug Fixes

    • Result Number now correctly honors the “Start Number” setting (including reverse order) and respects view filters and approval status.
    • Consistent numbering across pages and in single-entry views.
  • Documentation

    • Changelog updated to note the fix for the “Start Number” behavior.
  • Tests

    • Comprehensive new unit tests covering sequencing, pagination, reverse mode, filters, merge tags; some legacy sequence tests removed.

💾 Build file (766157e).

The Result Number (sequence) field was always starting at 0 instead of using the configured "Start Number" value in View settings. This only affected field display in Views - the {sequence} merge tag worked correctly.

Changes:
- Add configuration reading in get_sequence() method to load start/reverse settings from View
- Refactor get_sequence() into smaller, testable methods
- Add comprehensive test coverage including filters, pagination, and single entry views
- Consolidate scattered sequence tests into single test file
- Fix single entry sequence calculation to respect filters and sort order

Fixes #2431

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

coderabbitai bot commented Aug 22, 2025

Walkthrough

Rewrites the Sequence field to support single-entry positioning via captured unpaginated SQL, paginated multi-entry sequencing with per-context caching, honoring field "Start" and "Reverse" settings, and adds helpers and tests; updates changelog.

Changes

Cohort / File(s) Summary
Sequence field core logic
includes/fields/class-gravityview-field-sequence.php
Rewrote sequencing to support three modes (single-entry positioning, paginated multi-entry, sequential per-context). Added per-context start cache, SQL capture for single-entry positioning, helpers (ensure_field_configuration, get_context_key, is_single_entry_view, capture_view_sql_query, get_all_entry_results, find_entry_position, calculate_starting_number, get_next_sequence_number), and a gravityview/field/sequence/value filter.
Docs / Changelog
readme.txt
Added a "develop" changelog entry under 2.44 noting the Result Number (sequence) field now respects the "Start Number" setting.
New comprehensive tests
tests/unit-tests/GravityView_Field_Sequence_Test.php
Added extensive unit tests covering default/custom starts, negative/zero starts, reverse mode, pagination, single-entry behavior, view/filter/approval interactions, SQL ID-only optimization assertions, numeric-string handling, merge-tag behavior, and test widget helper classes.
Removed legacy tests
tests/unit-tests/GravityView_Field_Test.php, tests/unit-tests/GravityView_Future_Test.php
Removed older sequence-related test methods that were superseded by the new suite.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant View as View Renderer
  participant Field as Sequence Field
  participant Cache as Context Cache
  participant GFQ as GF Query Builder / DB
  participant Coll as Entry Collection

  User->>View: Request page or single-entry
  View->>Field: get_sequence(context)
  alt Single-entry view (position by full result set)
    Field->>GFQ: Hook & capture unpaginated SQL (capture_view_sql_query)
    GFQ-->>Coll: Execute full IDs query
    Field->>Coll: find_entry_position(entry_id)
    Field-->>View: compute number (start ± position, reverse applied)
  else Multi-entry view (paginated / streaming)
    Field->>Cache: get_or_init_start(context) (calculate_starting_number)
    Cache-->>Field: current start value
    Field->>Cache: update cached counter (get_next_sequence_number)
    Field-->>View: return filtered sequence value (gravityview/field/sequence/value)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Assessment against linked issues

Objective Addressed Explanation
Result Number field honors “Start Number” setting in Views [#2431]

Poem

I hop the rows from set-off start,
Count each view with careful heart.
SQL traced and caches kept,
Numbers rise where they once slept.
A rabbit's tally — neat and smart.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 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 6a7c4bf and 766157e.

📒 Files selected for processing (1)
  • readme.txt (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • readme.txt
⏰ 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: test_and_package
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue/2431-sequence-field

🪧 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 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: 2

🧹 Nitpick comments (7)
tests/unit-tests/GravityView_Field_Sequence_Test.php (3)

97-105: Avoid assigning non-array values to $_GET

$_GET = 0; can cause unexpected behavior outside this test (e.g., Utils::_GET expects an array-like). Prefer clearing the specific key or resetting to an array.

Apply this diff:

-        $_GET = 0;
+        unset( $_GET['pagenum'] );
+        // Or if you intend to fully reset test query args:
+        $_GET = [];

106-113: Nit: unused loop variable creates static analysis noise

foreach ( range( 1, 10 ) as $_ ) triggers PHPMD UnusedLocalVariable. Either switch to a for loop or add an inline suppression.

Example minimal change:

-        foreach ( range( 1, 10 ) as $_ ) {
+        for ( $i = 0; $i < 10; $i++ ) {
             \GV\GF_Entry::from_entry( $this->factory->entry->create_and_get( [
                 'form_id' => $form['id'],
                 'status' => 'active',
             ] ) );
-        }
+        }

Alternatively, add a method-level docblock @SuppressWarnings(PHPMD.UnusedLocalVariable).


579-668: Filtered single-entry test is great; add negative assertion comment / suppression for “unused” entries

Entries intentionally created to be filtered out ($entry_2, $entry_4) are unused variables from a static analysis perspective. Either reference them in a negative assertion (e.g., verify they yield 0 if resolved) or suppress PHPMD warnings for the method.

includes/fields/class-gravityview-field-sequence.php (4)

136-157: Grammar fix in log: “used outside of”

Minor but user-facing in logs: “was used without outside of the GravityView entry loop” reads awkwardly.

Apply this diff:

-            gravityview()->log->error( '{sequence} Merge Tag was used without outside of the GravityView entry loop.', array( 'data' => $matches ) );
+            gravityview()->log->error( '{sequence} Merge Tag was used outside of the GravityView entry loop.', array( 'data' => $matches ) );

223-231: Docblocks with “@SInCE TODO” should be finalized before release

There are multiple “@SInCE TODO” placeholders. Please replace with the correct version before shipping.


408-411: Performance consideration: selecting only IDs would reduce memory for large result sets

$wpdb->get_results( implode( ' ', $sql_query ), ARRAY_A ) fetches all columns. If possible, adjust the captured SELECT to only include the entry ID to minimize memory pressure on large Views. Alternatively, add a filter to let integrators switch the projection.


367-397: Improve Resilience of SQL Capture & Override

Capturing and manipulating the raw SQL generated by Gravity Forms via the gform_gf_query_sql filter works today but relies on internal array keys (paginate, order) and the t1 table alias—both of which could change in future GF releases or custom query contexts. To reduce breakage risk and enable rapid rollback:

  • Gate the custom ORDER BY override behind a filter so it can be turned off without code changes.
  • Emit the full captured $sql_query to the debug log when debugging is enabled, for faster diagnosis if the shape changes.
  • Where possible, use the GravityView/GF entry API (e.g. fetch all entry IDs via API parameters) instead of rebuilding raw SQL manually.

Suggested patch to add a filter-based “escape hatch” and leave room for debug logging:

         // Remove pagination to get all results
         unset( $sql_query['paginate'] );

-        // For single entry views with a custom start value, sort by ID ASC to get
-        // consistent sequence numbers based on creation order
-        // Only override if start value is different from default (1)
-        if ( $this->is_single_entry_view( $context ) && $context->field->start !== 1 ) {
-            $sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
-        }
+        // Optionally force an ASC order on single-entry views with a custom start
+        $force_asc = apply_filters(
+            'gk/gravityview/field/sequence/single/force_asc_on_custom_start',
+            true,
+            $context,
+            $sql_query
+        );
+        if ( $force_asc && $this->is_single_entry_view( $context ) && $context->field->start !== 1 ) {
+            $sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
+        }
+
+        /**
+         * Log the full SQL query shape when debugging is enabled.
+         * Developers can inspect changes to array keys or table aliases.
+         */
+        if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
+            error_log( '[GravityView] Captured SQL Query: ' . print_r( $sql_query, true ) );
+        }
  • File: includes/fields/class-gravityview-field-sequence.php
  • Method: capture_view_sql_query() (lines 367–397)

Optional: In high-risk environments, consider replacing raw SQL capture entirely with the View’s entry API (get_entries() plus API parameters to load all IDs) to avoid dependency on internal SQL structures.

📜 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 8820e47 and e2d74c8.

📒 Files selected for processing (5)
  • includes/fields/class-gravityview-field-sequence.php (1 hunks)
  • readme.txt (1 hunks)
  • tests/unit-tests/GravityView_Field_Sequence_Test.php (1 hunks)
  • tests/unit-tests/GravityView_Field_Test.php (0 hunks)
  • tests/unit-tests/GravityView_Future_Test.php (0 hunks)
💤 Files with no reviewable changes (2)
  • tests/unit-tests/GravityView_Future_Test.php
  • tests/unit-tests/GravityView_Field_Test.php
🧰 Additional context used
🧬 Code graph analysis (2)
tests/unit-tests/GravityView_Field_Sequence_Test.php (5)
tests/GV_UnitTestCase.php (1)
  • GV_UnitTestCase (3-80)
includes/fields/class-gravityview-fields.php (1)
  • GravityView_Fields (14-168)
includes/fields/class-gravityview-field-sequence.php (1)
  • get_sequence (234-257)
future/includes/class-gv-collection-field.php (1)
  • by_visible (97-107)
future/includes/class-gv-view.php (1)
  • _flush_cache (859-865)
includes/fields/class-gravityview-field-sequence.php (3)
future/includes/class-gv-view.php (1)
  • get_anchor_id (1868-1877)
future/includes/class-gv-utils.php (2)
  • Utils (12-193)
  • _GET (21-23)
future/includes/class-gv-collection-entry.php (1)
  • total (104-121)
🪛 PHPMD (2.15.0)
tests/unit-tests/GravityView_Field_Sequence_Test.php

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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


1085-1085: Avoid unused parameters such as '$content'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ 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: test_and_package
🔇 Additional comments (16)
readme.txt (1)

37-37: Changelog entry is clear and scoped to the underlying bug

Nice, this line concisely communicates the user-visible fix for the Result Number field respecting “Start Number” in Views. No action needed.

tests/unit-tests/GravityView_Field_Sequence_Test.php (12)

36-39: Good: centralizing a reusable Sequence field instance

Fetching the registered 'sequence' field in setUp() keeps tests DRY and consistent.


144-197: Good: deterministic single-entry tests with cache disabled

Disabling both GV and GF caches here is the right move to ensure consistent, deterministic results while reconstructing full result sets.


205-250: Solid coverage: field-configured 'start' respected for multi-entry views

This exercises the core regression. Consider adding one extra assertion for a second page (set $_GET['pagenum']=2) to ensure paging + configured start keeps working.


256-296: Good coverage for negative and zero starts

These tests are valuable edge cases. No changes required.


348-415: Great scenario: reverse + custom start with total/partial pages

Good to see both entries->all() and entries->total() asserted. One suggestion: add an assertion that the reverse sequence still honors the View sorting settings (if any) to guard against order overrides in the implementation.


500-573: Nice: single-entry with custom start verifies first and last positions

This validates the “position-based” numbering end-to-end. No action needed.


674-750: Default sort behavior confirmed; consider a parallel test for explicit sort ASC

This test assumes default DESC order. Please add a companion test setting an explicit ASC order on the View to ensure single-entry position math tracks custom sort directions, too.


756-859: Comprehensive: multi-filter + approval + start value

Great multi-constraint validation. Also good to see the 0 result asserted for out-of-scope entries.


865-902: Invalid start defaults to 1: exact behavior locked

Clear and helpful test for resilience against bad configuration values.


909-920: Helpful helper: context reset between tests

This local reset mirrors GV test infra; good hygiene.


927-963: Merge-tag test: covers positive and negative explicit starts

Good coverage; no change needed.


970-1067: End-to-end merge-tag rendering coverage is excellent

Thorough validation across fields, custom classes, and widgets (including the “not working in widgets” expectation). Great job consolidating this into one place.

includes/fields/class-gravityview-field-sequence.php (3)

300-309: Context key choice looks good

Using the view anchor ID and field UID is a sensible per-context cache key and should be stable within a request.


320-322: Guard for missing request in single-entry detection

$context->request && $context->request->is_entry() is fine, but if $context->request isn’t set, this short-circuits correctly. No action needed.


536-551: Nice touch: allow filtering the final sequence value

The gravityview/field/sequence/value filter is a useful extension point for formatting or transformations.

zackkatz and others added 7 commits August 22, 2025 15:37
Previously, the Result Number field would incorrectly override a "0" start value due to using empty() check, which treats "0" as empty. This improvement switches to using is_numeric() to properly preserve numeric string values including "0".

- Changed condition from `empty() && !== 0` to `!is_numeric()` for better numeric string handling
- Added comprehensive test coverage for numeric string start values including "0", negative numbers, and edge cases
- Ensures Start Number configuration is respected for all valid numeric values

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Previously, reverse mode used GFAPI::count_entries() which ignored View filters, leading to incorrect sequence numbers. This commit makes several improvements:

1. Prioritize View's entries collection for total count in reverse mode
   - Respects all View filters, search criteria, and approval status
   - Removes misleading GFAPI fallback that counted unfiltered entries
   - Defaults safely to 1 if View collection unavailable

2. Optimize SQL to only select entry IDs for memory efficiency
   - Reduces memory usage significantly for large result sets
   - Changes SELECT clause from all columns to just `t1`.`id`
   - Particularly beneficial for Views with many entries or complex fields

These changes ensure reverse sequence numbers are accurate and the implementation is more memory-efficient.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Adds extensive test coverage for the sequence field fixes:

- Test that numeric string start values (especially "0") are preserved correctly
- Test that reverse mode respects View filters and approval status
- Test that reverse mode handles empty/filtered views gracefully
- Test SQL optimization to verify only IDs are selected
- Test edge cases and fallback scenarios

These tests ensure the sequence field behaves correctly with:
- Filtered Views
- Approval-only Views
- Views with no matching entries
- Various start values including 0 and negative numbers
- Large datasets with memory optimization

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
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

♻️ Duplicate comments (1)
includes/fields/class-gravityview-field-sequence.php (1)

276-281: Addresses the "Start Number" override bug correctly (numeric checks + config read).

Switching to is_numeric() preserves explicit "0" and other numeric strings; loading reverse from configuration is straightforward. This closes the root cause reported in #2431 without side effects.

Also applies to: 286-289

🧹 Nitpick comments (11)
includes/fields/class-gravityview-field-sequence.php (5)

483-489: Prefer $context->request when available to resolve totals under the same request context.

Using the global request can diverge from the rendering context when multiple Views exist on a page. Fall back to the global only if the context doesn’t define one.

-                $request = gravityview()->request;
-                if ( $request ) {
+                $request = isset( $context->request ) ? $context->request : gravityview()->request;
+                if ( $request ) {
                     $entries_collection = $context->view->get_entries( $request );

320-322: Return a strict boolean from is_single_entry_view for clarity.

You currently return the entry object (truthy) or false. Cast to bool to match the method’s contract and improve readability.

-        return $context->request && $context->request->is_entry();
+        return (bool) ( $context->request && $context->request->is_entry() );

266-271: Replace “@SInCE TODO” placeholders with the release version before merging.

Docblocks should reflect the actual version that ships the change to keep API history accurate.

Also applies to: 294-299, 312-319, 324-336, 358-366, 404-412, 418-428, 454-466, 518-529, 546-553


340-416: Sanity checks around captured SQL array shape.

gform_gf_query_sql generally yields a parts array, but defensive checks improve resilience. If a plugin alters the filter and returns a string, implode(' ', $sql_query) would behave unexpectedly.

Consider guarding with:

-        // Remove pagination to get all results
-        unset( $sql_query['paginate'] );
+        // Normalize and guard against unexpected filter output
+        if ( ! is_array( $sql_query ) ) {
+            return array();
+        }
+        unset( $sql_query['paginate'] );

412-416: Potential performance hotspot on large datasets (single-entry path).

Fetching all IDs for the full result set is acceptable with the IDs-only optimization, but it’s still O(N). If needed later, consider a rank/position query (window function) when supported, or a bounded seek using the View’s sort to compute position without scanning all rows.

tests/unit-tests/GravityView_Field_Sequence_Test.php (6)

106-113: Avoid unused loop variable to appease static analysis and improve clarity.

Switch to a for-loop and drop the unused $_ variable.

-        foreach ( range( 1, 10 ) as $_ ) {
+        for ( $i = 1; $i <= 10; $i++ ) {
             \GV\GF_Entry::from_entry( $this->factory->entry->create_and_get( [
                 'form_id' => $form['id'],
                 'status' => 'active',
             ] ) );
-        }
+        }

813-836: Remove unused local variables in filtered single-entry setup.

$entry_2, $entry_3, and $entry_4 aren’t referenced; create those entries without assigning to variables.

-        $entry_2 = $this->factory->entry->create_and_get( [
+        $this->factory->entry->create_and_get( [
             'form_id' => $form['id'],
             'status' => 'active',
             '1' => 'Exclude', // This will be filtered out
         ] );
-
-        $entry_3 = $this->factory->entry->create_and_get( [
+        $this->factory->entry->create_and_get( [
             'form_id' => $form['id'],
             'status' => 'active',
             '1' => 'Include',
         ] );
-
-        $entry_4 = $this->factory->entry->create_and_get( [
+        $this->factory->entry->create_and_get( [
             'form_id' => $form['id'],
             'status' => 'active',
             '1' => 'Exclude', // This will be filtered out
         ] );

Also applies to: 825-830


908-912: Remove unused $entry_2 in default-sort single-entry test.

-        $entry_2 = $this->factory->entry->create_and_get( [
+        $this->factory->entry->create_and_get( [
             'form_id' => $form['id'],
             'status' => 'active',
             '1' => 'Hide', // This will be filtered out
         ] );

1135-1136: Drop unused $wpdb import in SQL optimization test.

The test uses the query filter and doesn’t reference $wpdb.

-        global $wpdb;
-        $captured_query = null;
+        $captured_query = null;

895-971: Add a variant: single-entry + custom start + custom sort order.

To prevent regressions, add a test where the View sorts by a field or created date DESC and start is non-default, asserting that the position respects the View’s sort. This will catch the potential ORDER BY override issue flagged in the PHP code review.


1429-1446: Ignore unused $content parameter via annotation to quiet PHPMD.

Signature must match the parent, so suppress the warning instead of changing it.

You can add to the method docblock:

/**
 * @param string $content
 * @noinspection PhpUnusedParameterInspection
 */
📜 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 e2d74c8 and 6a7c4bf.

📒 Files selected for processing (2)
  • includes/fields/class-gravityview-field-sequence.php (1 hunks)
  • tests/unit-tests/GravityView_Field_Sequence_Test.php (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
includes/fields/class-gravityview-field-sequence.php (4)
future/includes/class-gv-view.php (1)
  • get_anchor_id (1868-1877)
future/includes/class-gv-utils.php (1)
  • _GET (21-23)
future/includes/class-gv-collection-entry.php (1)
  • total (104-121)
future/includes/class-gv-collection.php (1)
  • count (97-99)
tests/unit-tests/GravityView_Field_Sequence_Test.php (6)
tests/GV_UnitTestCase.php (1)
  • GV_UnitTestCase (3-80)
tests/unit-tests/GravityView_Future_Test.php (2)
  • setUp (13-17)
  • _reset_context (26-40)
includes/fields/class-gravityview-fields.php (1)
  • GravityView_Fields (14-168)
future/includes/class-gv-field-internal.php (1)
  • Internal_Field (14-139)
future/includes/class-gv-utils.php (2)
  • _GET (21-23)
  • Utils (12-193)
future/includes/class-gv-view.php (1)
  • _flush_cache (859-865)
🪛 PHPMD (2.15.0)
tests/unit-tests/GravityView_Field_Sequence_Test.php

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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


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

(UnusedLocalVariable)


1439-1439: Avoid unused parameters such as '$content'. (Unused Code Rules)

(UnusedFormalParameter)

⏰ 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: test_and_package
🔇 Additional comments (1)
tests/unit-tests/GravityView_Field_Sequence_Test.php (1)

349-416: Great coverage for reverse + custom start, including total() vs all().

The assertions around total() and per-page counts validate the reverse-start logic well. Nicely done.

Comment on lines +393 to +398
// For Single Entry context with a custom start value, sort by ID ASC to get
// consistent sequence numbers based on creation order
// Only override if start value is different from default (1)
if ( $this->is_single_entry_view( $context ) && $context->field->start !== 1 ) {
$sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Don’t override the View’s sort order for single-entry with custom start; it breaks correctness for custom-sorted Views.

For single-entry Views, forcing ORDER BY \t1`.`id` ASCwheneverstart !== 1` ignores the View’s configured sort (e.g., date DESC, custom field, multiple columns). That will yield incorrect positions and therefore incorrect sequence numbers. Preserve the captured order unless it’s empty.

Apply this diff:

-        // For Single Entry context with a custom start value, sort by ID ASC to get
-        // consistent sequence numbers based on creation order
-        // Only override if start value is different from default (1)
-        if ( $this->is_single_entry_view( $context ) && $context->field->start !== 1 ) {
-            $sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
-        }
+        // Preserve the View's configured sort order. Only provide a default if none exists.
+        if ( $this->is_single_entry_view( $context ) && $context->field->start !== 1 && empty( $sql_query['order'] ) ) {
+            $sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
+        }

Follow-up: consider adding a unit test “single_entry_with_custom_start_and_custom_sort” to assert sequences reflect the View’s sort field and direction, not creation order.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// For Single Entry context with a custom start value, sort by ID ASC to get
// consistent sequence numbers based on creation order
// Only override if start value is different from default (1)
if ( $this->is_single_entry_view( $context ) && $context->field->start !== 1 ) {
$sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
}
// Preserve the View's configured sort order. Only provide a default if none exists.
if ( $this->is_single_entry_view( $context )
&& $context->field->start !== 1
&& empty( $sql_query['order'] ) ) {
$sql_query['order'] = 'ORDER BY `t1`.`id` ASC';
}

@zackkatz zackkatz changed the title Fix Result Number field not respecting Start Number configuration [WIP] Fix Result Number field not respecting Start Number configuration Aug 25, 2025
@Mwalek
Copy link
Contributor

Mwalek commented Aug 26, 2025

Test field in Single Entry on Views that have Advanced Filters configured (in order to make sure that this works for not just simple, ordered results)

@zackkatz is this really supposed to work for the single entry page?

I get a database error (see image below) when I add the Result Number field to the Single Entry layout. And it definitely doesn't respect the "First Number in the Sequence" setting.

Screenshot 2025-08-26 at 10 55 43 AM

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

Successfully merging this pull request may close these issues.

Result Number field always starts at 0 regardless of "Start Number" setting
2 participants