Skip to content

Use exact option names in single-option actions - #92

Open
ilicfilip wants to merge 1 commit into
developfrom
filip/fix-option-name-handling
Open

ilicfilip wants to merge 1 commit into
developfrom
filip/fix-option-name-handling

Conversation

@ilicfilip

Copy link
Copy Markdown
Collaborator

Row actions (toggle autoload, delete, create option with value false) could miss the option shown in the table, or reach the server with an empty name.

What was wrong

  • jQuery .data() parses the name. handleTableActions read the name with button.data( 'option' ), which turns JSON-like names into values: ["foo"] became an array (sent as option_name[]=foo), {"a":1} an object, and null an empty value. Bulk delete already read the raw attribute with getAttribute( 'data-option' ).
  • sanitize_text_field() changed names. The three single-option routes ran option_name through it, so a b became a b, a<b>c became ac, and so on. The action then missed the option or targeted a different one.
  • <tr> ids repeated across tables. An option listed in both "All options" and another table got the same row id in both.

Changes

  • handleTableActions reads button.attr( 'data-option' ).
  • update-autoload, delete-option and create-option-false share get_option_name_arg(): type: string, minLength: 1, maxLength: 191, no sanitize_callback. Arrays and objects now get a 400 instead of relying on sanitize_text_field() returning ''.
  • New getTableRowId() prefixes row ids with the table id. Single actions and bulk delete look rows up through it.

Testing

On a local site:

  • REST as admin: array, object, empty and 192-character names return 400; aaaoo two spaces and aaaoo<b>tag are toggled exactly, no altered copy is created
  • Browser, real row buttons in "All options": toggle and delete ["siteurl"], {"a":1}, null, 123, aaaoo two spaces, aaaoo<b>tag; each request sends the exact name, returns 200, and the options are gone from the database afterwards; siteurl unchanged
  • "Unused" (server-side): remove autoload from a JSON-named option, row drops out of the list
  • Bulk delete two options (one JSON-named) from "All options"
  • No duplicate plugin ids on the page; console clean on load and after the actions
  • "Create option with value false" button (same code path, not clicked)

Lint: PHPCS clean, PHPStan unchanged (44 existing errors), lint:js only the existing prettier error in the migration code.

🤖 Generated with Claude Code

- Read the row button's option name with .attr( 'data-option' ). jQuery's
  .data() parses JSON-like names such as '["foo"]', '{"a":1}' or 'null', so
  those were sent as arrays or empty values. The bulk-delete path already
  reads the raw attribute.
- The update-autoload, delete-option and create-option-false routes now
  require option_name to be a string of 1 to 191 characters, and no longer
  run it through sanitize_text_field(), which changed names like 'a  b' or
  'a<b>c' and made the action miss or hit a different option.
- Include the table id in DataTables row ids, so <tr> ids stay unique when
  an option is listed in more than one table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Test on Playground
Test this pull request on the Playground
or download the zip

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.

1 participant