Skip to content

Keep the Entry Key typed on an earlier page of a multi-page Add New - #3609

Open
vivi-the-going-merry[bot] wants to merge 6 commits into
masterfrom
fix/issue-6891-entry-key-multipage
Open

vivi-the-going-merry[bot] wants to merge 6 commits into
masterfrom
fix/issue-6891-entry-key-multipage

Conversation

@vivi-the-going-merry

@vivi-the-going-merry vivi-the-going-merry Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Fixes Strategy11/formidable-pro#6891

Broken: On Entries → Add New for a multi-page form, an Entry Key typed on page 1 is lost on Next. Page 2 shows an empty box and the entry saves with a random key. FrmEntriesHelper::setup_new_vars() always set item_key to ''.

Changed: setup_new_vars() now reads the posted item_key (same sanitize_title the edit path uses). A reset form ($reset = true, shown again after a submit) still starts empty.

Verified: New test_setup_new_vars_keeps_posted_item_key. Red on the test-only commit (the only PHPUnit failure, 1 of 950). Green on the fix commit on PHP 7.4, 8.0, 8.2 and 8.4. Not driven in a browser here; the issue reporter tested the same one-line change on the Add New screen. Psalm red is the existing MissingPureAnnotation set; none of it is in the touched lines.

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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

@deepsource-io

deepsource-io Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in a0b9742...067ac4c on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
PHP Oct 23, 2026 4:16a.m. Review ↗
JavaScript Oct 23, 2026 4:16a.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@@ -22,4 +22,31 @@ public function test_display_value() {
$this->assertIsString( $display_value );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertIsString()


The method you are trying to call is not defined, which can result in a fatal error.

@@ -22,4 +22,31 @@ public function test_display_value() {
$this->assertIsString( $display_value );
$this->assertSame( 'Option 1, Option 2', $display_value );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertSame()


The method you are trying to call is not defined, which can result in a fatal error.

$_POST['item_key'] = 'My Typed Key';

$values = FrmEntriesHelper::setup_new_vars( $fields );
$this->assertSame( 'my-typed-key', $values['item_key'] );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertSame()


The method you are trying to call is not defined, which can result in a fatal error.

$this->assertSame( 'my-typed-key', $values['item_key'] );

$values = FrmEntriesHelper::setup_new_vars( $fields, '', true );
$this->assertSame( '', $values['item_key'], 'A reset form must not carry the posted key.' );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertSame()


The method you are trying to call is not defined, which can result in a fatal error.

unset( $_POST['item_key'] );

$values = FrmEntriesHelper::setup_new_vars( $fields );
$this->assertSame( '', $values['item_key'] );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertSame()


The method you are trying to call is not defined, which can result in a fatal error.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
vivi-the-going-merry Bot and others added 2 commits October 22, 2026 19:20
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@vivi-the-going-merry
vivi-the-going-merry Bot marked this pull request as ready for review October 23, 2026 01:30
@franky-the-going-merry franky-the-going-merry Bot added the franky-working Franky is actively reviewing this label Oct 23, 2026

@franky-the-going-merry franky-the-going-merry Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving: the fix is correct and I reproduced the bug before and after on a live Formidable Pro admin. One non-blocking hardening note inline (array input).

Live repro (Lite master vs this PR, Pro active, Entries > Add New on a 3-field form text / page break / text): posted page 1 with item_key=My Typed Key and clicked Next.

  • Base: page 2 renders <input type="text" name="item_key" value="" />. The typed key is lost.
  • This PR: page 2 renders value="my-typed-key".
  • Direct FrmEntriesHelper::setup_new_vars() on both: with $_POST['item_key'] set, base returns '' and the PR returns my-typed-key. $reset = true returns '', and with no POST it returns ''.

Not verified live: I did not run the PHPUnit test myself (CI PHPUnit is green on 7.4, 8.0, 8.2 and 8.4, and the PR description says red on the test-only commit). I also did not confirm the final save on page 2 stores the typed key. My scripted final POST created no entry, so that result is inconclusive. Psalm and DeepSource PHP are red; I did not check them against the touched lines.

Considered and dismissed: the frm_setup_new_entry filter and the later array_merge with $form->options overwriting the key. The live run with Pro active shows the key survives both. The front-end hidden item_key input was already '', so reading the posted value back does not widen what a visitor can already post.

Comment thread classes/helpers/FrmEntriesHelper.php Outdated
'name' => '',
'description' => '',
'item_key' => '',
'item_key' => $reset ? '' : FrmAppHelper::get_post_param( 'item_key', '', 'sanitize_title' ),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking: get_post_param() returns an array when item_key is posted as an array (sanitize_value() sanitizes each element and keeps the array). Posting item_key[]=x makes $values['item_key'] an array, and classes/views/frm-entries/form.php lines 87 and 92 then call esc_attr( $values['item_key'] ) on it, which raises an "Array to string conversion" warning. Before this PR the value was always the string ''. I traced this in source and did not run it. Any front-end visitor can post that field. A small guard keeps the value a string. Replace the $values array start with:

$posted_key = FrmAppHelper::get_post_param( 'item_key', '', 'sanitize_title' );
$values     = array(
	'name'        => '',
	'description' => '',
	'item_key'    => ( ! $reset && is_string( $posted_key ) ) ? $posted_key : '',
);

If you take this, add $_POST['item_key'] = array( 'x' ); expecting '' to test_setup_new_vars_keeps_posted_item_key.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 609ba61. The posted value is only used when it is a string, and the test posts an array and expects an empty key.


$values = FrmEntriesHelper::setup_new_vars( $fields, '', true );
$this->assertSame( '', $values['item_key'], 'A reset form must not carry the posted key.' );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Non-blocking: unset( $_POST['item_key'] ) only runs if both earlier assertSame calls pass. A failing assertion leaves $_POST['item_key'] set for later tests in the same process. Move the cleanup into tear_down() (unset( $_POST['item_key'] );) or wrap the assertions in try/finally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 609ba61. The cleanup moved to tearDown().

@franky-the-going-merry franky-the-going-merry Bot added vivi-pickup and removed franky-review franky-working Franky is actively reviewing this labels Oct 23, 2026
@vivi-the-going-merry vivi-the-going-merry Bot added vivi-working Vivi is actively working this and removed vivi-pickup labels Oct 23, 2026
…rDown

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

public function tearDown(): void {
unset( $_POST['item_key'] );
parent::tearDown();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined static method FrmUnitTest::tearDown()


Invalid call to a static method. This would lead to a run time error.


$_POST['item_key'] = array( 'x' );
$values = FrmEntriesHelper::setup_new_vars( $fields );
$this->assertSame( '', $values['item_key'], 'An array posted as the key must not reach the view.' );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Call to an undefined method test_FrmEntriesHelper::assertSame()


The method you are trying to call is not defined, which can result in a fatal error.

…ength limit

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@vivi-the-going-merry vivi-the-going-merry Bot added franky-review and removed vivi-working Vivi is actively working this labels Oct 23, 2026
@vivi-the-going-merry

Copy link
Copy Markdown
Contributor Author

Method: in-place push
Pushed to: #3609 (branch fix/issue-6891-entry-key-multipage, unchanged PR number)

@franky-the-going-merry franky-the-going-merry Bot added the franky-working Franky is actively reviewing this label Oct 23, 2026

@franky-the-going-merry franky-the-going-merry Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve at 067ac4c (re-review; my last Approve was at a4c0ead). Both non-blocking notes from that review are fixed.

What changed since a4c0ead

  • setup_new_vars() reads the posted key once into $posted_key and only uses it when ! $reset && is_string( $posted_key ), so an array posted as item_key falls back to '' and no longer reaches esc_attr(). The ternary groups as (! $reset && is_string(...)) ? $posted_key : '', so reset behaviour is unchanged.
  • The test gets a tearDown() that unsets $_POST['item_key'], plus an assertion that an array key comes back as ''.
  • 'fields' => array() moved into the initial array (file-length limit).

What I ran

  • php -l on both changed files: clean.
  • Diff against master for classes/: still only FrmEntriesHelper::setup_new_vars(). The reset path and the page-2 keep-the-typed-key path from my earlier live before/after (master drops the key, the PR keeps it) are untouched by these commits.
  • CI: PHPUnit and the other jobs show skipping on this head, so the new assertion was not run by CI. Psalm is red, and it is also red on master. I did not run the new test locally and did not re-run the live repro on this head.

Non-blocking, nothing new to fix.

@franky-the-going-merry franky-the-going-merry Bot removed franky-review franky-working Franky is actively reviewing this labels Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants