Skip to content

Toggle columns#291

Open
Dan0sz wants to merge 2 commits intodevelopfrom
toggle_columns
Open

Toggle columns#291
Dan0sz wants to merge 2 commits intodevelopfrom
toggle_columns

Conversation

@Dan0sz
Copy link
Collaborator

@Dan0sz Dan0sz commented Mar 25, 2026

Summary by CodeRabbit

  • Admin

    • Enhanced admin settings interface with improved field organization and layout for better usability.
  • Chores

    • Updated development tooling with new build scripts.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

Two files were modified: package.json received a new watch npm script, and API.php underwent array access syntax standardization alongside UI rendering updates for grouped settings fields.

Changes

Cohort / File(s) Summary
NPM Configuration
package.json
Added new watch npm script executing cross-env webpack --watch for development builds.
Admin Settings Module
src/Admin/Settings/API.php
Standardized array access syntax throughout file; introduced $columns-based wrapper div and conditional grouping logic in render_group_field for specific field slugs; updated HTML attributes and hook invocations to reference updated array access forms.

Poem

🐰 A rabbit hops through arrays bright,

With brackets spaced just right, just right!

Watch scripts now guide the webpack way,

While grouped fields dance and sway, hooray!

Settings shimmer, cleaner still—thump thump 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Toggle columns' directly relates to the main change in the PR: adding column-based wrapper div and conditional grouping for specific field slugs in render_group_field method.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch toggle_columns

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 and usage tips.

@codecov
Copy link

codecov bot commented Mar 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@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.

🧹 Nitpick comments (6)
src/Admin/Settings/API.php (6)

580-581: Consider making column layout configurable via group definition.

The column layout is hardcoded for specific slugs. For better maintainability, consider adding a 'columns' key to the group definitions in Page.php instead.

Alternative approach
-		$fields  = $group['fields'];
-		$columns = $group['slug'] === 'tracked_user_roles' || $group['slug'] === 'expand_dashboard_access' ? 'md:!mt-2 md:flex md:flex-wrap' : '';
+		$fields  = $group['fields'];
+		$columns = ! empty( $group['columns'] ) ? $group['columns'] : '';

Then in Page.php, add to the group definitions:

[
    'label'   => esc_html__( 'Track analytics for user roles', 'plausible-analytics' ),
    'slug'    => 'tracked_user_roles',
    'columns' => 'md:!mt-2 md:flex md:flex-wrap',
    // ...
],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` around lines 580 - 581, The code currently
hardcodes column CSS based on group slugs in Admin/Settings/API.php (see
$columns using $group['slug']); update to read an optional 'columns' key from
each group definition (add 'columns' => 'md:!mt-2 md:flex md:flex-wrap' to
groups in Page.php) and use that value if present, falling back to the existing
slug-based or empty string logic; adjust the assignment of $columns in the
render logic to prefer $group['columns'] when set, otherwise keep the current
behavior.

502-505: Apply consistent output escaping.

While these values come from the controlled get_quick_actions() method, WordPress coding standards recommend escaping at the point of output for defense-in-depth.

Suggested improvement
-				<a id="<?php echo $quick_action['id']; ?>" class="no-underline text-sm leading-6 text-gray-900"
-				   target="<?php echo $quick_action['target']; ?>" href="<?php echo $quick_action['url']; ?>"
-				   title="<?php echo $quick_action['label']; ?>">
-					<?php echo $quick_action['label']; ?>
+				<a id="<?php echo esc_attr( $quick_action['id'] ); ?>" class="no-underline text-sm leading-6 text-gray-900"
+				   target="<?php echo esc_attr( $quick_action['target'] ); ?>" href="<?php echo esc_url( $quick_action['url'] ); ?>"
+				   title="<?php echo esc_attr( $quick_action['label'] ); ?>">
+					<?php echo esc_html( $quick_action['label'] ); ?>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` around lines 502 - 505, The output for quick
action attributes isn't escaped at point of output; update the rendering in the
loop that consumes get_quick_actions() so each value is properly escaped: use
esc_attr() for id and target and title, esc_url() for the href, and esc_html()
(or esc_html_e/esc_html depending on context) for the label text when echoing
$quick_action['id'], $quick_action['target'], $quick_action['url'],
$quick_action['label'] inside the anchor; keep the existing keys and structure
but wrap each echoed value with the appropriate escaping function to satisfy
WordPress coding standards.

753-753: Escape the checkbox label output.

For consistency with WordPress coding standards:

Suggested fix
-			<span class="ml-2 dark:text-gray-100 text-lg"><?php echo $field['label']; ?></span>
+			<span class="ml-2 dark:text-gray-100 text-lg"><?php echo esc_html( $field['label'] ); ?></span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` at line 753, The checkbox label is output
unescaped via "<?php echo $field['label']; ?>" which can expose XSS; update the
span to echo the escaped label using esc_html() for $field['label'] (i.e.,
replace the direct echo with an escaped output of $field['label']), keeping the
surrounding span and class intact.

555-565: Apply escaping to group field outputs.

The $group['slug'] is used in HTML attributes including an onclick handler. Escaping prevents potential issues if slugs contain special characters.

Suggested improvement
-		<div id="<?php echo $group['slug']; ?>_toggle" onclick="plausibleToggleSection('<?php echo $group['slug']; ?>')" class="flex items-center mt-4 space-x-3 hover:cursor-pointer">
+		<div id="<?php echo esc_attr( $group['slug'] ); ?>_toggle" onclick="plausibleToggleSection('<?php echo esc_js( $group['slug'] ); ?>')" class="flex items-center mt-4 space-x-3 hover:cursor-pointer">
 			<span class="dark:text-gray-100 text-lg">
-				<?php echo $group['label']; ?>
+				<?php echo esc_html( $group['label'] ); ?>
 			</span>
 			<!-- Chevron -->
-			<svg xmlns="http://www.w3.org/2000/svg" id="<?php echo $group['slug']; ?>_chevron" class="h-6 w-6 ml-2 text-gray-400 dark:text-gray-500 transition-transform duration-250" fill="none"
-				 viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
+			<svg xmlns="http://www.w3.org/2000/svg" id="<?php echo esc_attr( $group['slug'] ); ?>_chevron" class="h-6 w-6 ml-2 text-gray-400 dark:text-gray-500 transition-transform duration-250" fill="none"
+				 viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
 				<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5"/>
 			</svg>
 		</div>
-		<div class="hidden" id="<?php echo $group['slug']; ?>_content">
+		<div class="hidden" id="<?php echo esc_attr( $group['slug'] ); ?>_content">
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` around lines 555 - 565, Escape all outputs
derived from $group when writing into HTML attributes, IDs and inline JS to
prevent injection and broken markup: replace direct uses of $group['slug'] in id
attributes and the onclick handler (e.g., occurrences that build "<?php echo
$group['slug']; ?>_toggle", "<?php echo $group['slug']; ?>_chevron", "<?php echo
$group['slug']; ?>_content" and the plausibleToggleSection(...) call) with a
properly escaped value (use htmlspecialchars($group['slug'], ENT_QUOTES,
'UTF-8') for attribute/ID contexts and use json_encode($group['slug']) or
similar JS-escaping when embedding into the onclick string), and also escape
$group['label'] when rendering the visible text (e.g.,
htmlspecialchars($group['label'], ENT_QUOTES, 'UTF-8')).

129-129: Consider sanitizing $_GET['tab'] input.

The tab parameter is used directly without sanitization. While this is in the admin context, it's good practice to sanitize and validate against allowed values to prevent potential issues if an invalid tab is passed (which would access a non-existent key at line 153).

Suggested improvement
-		$current_tab = ! empty( $_GET['tab'] ) ? $_GET['tab'] : 'general';
+		$current_tab = ! empty( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
+		if ( ! isset( $this->fields[ $current_tab ] ) ) {
+			$current_tab = 'general';
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` at line 129, $current_tab is assigned directly
from $_GET['tab'] without sanitization; update the assignment to sanitize and
validate it against the allowed tab keys before use. Use a sanitized input
(e.g., cast to string and run through sanitize_text_field or equivalent) and
check it exists in your tabs list (the array used to render/lookup tabs,
referenced where $current_tab is later used) then fall back to 'general' if not
valid; ensure you modify the code around the $current_tab assignment and the
validation uses the same allowed-tabs array used elsewhere in the class.

587-587: Escape the group label output.

The label is output without escaping while the description below correctly uses wp_kses_post().

Suggested fix
-					<h3 class="text-lg mt-0 leading-6 font-medium text-gray-900 dark:text-gray-100" id="<?php echo $group['slug']; ?>"><?php echo $group['label']; ?></h3>
+					<h3 class="text-lg mt-0 leading-6 font-medium text-gray-900 dark:text-gray-100" id="<?php echo esc_attr( $group['slug'] ); ?>"><?php echo esc_html( $group['label'] ); ?></h3>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Admin/Settings/API.php` at line 587, The group label is echoed unescaped
(<?php echo $group['label']; ?>) which can introduce XSS; update the output to
escape the label using esc_html() when echoing $group['label']; also ensure the
id attribute using $group['slug'] is escaped with esc_attr() to be safe (adjust
the h3 rendering that references $group['slug'] and $group['label']
accordingly).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/Admin/Settings/API.php`:
- Around line 580-581: The code currently hardcodes column CSS based on group
slugs in Admin/Settings/API.php (see $columns using $group['slug']); update to
read an optional 'columns' key from each group definition (add 'columns' =>
'md:!mt-2 md:flex md:flex-wrap' to groups in Page.php) and use that value if
present, falling back to the existing slug-based or empty string logic; adjust
the assignment of $columns in the render logic to prefer $group['columns'] when
set, otherwise keep the current behavior.
- Around line 502-505: The output for quick action attributes isn't escaped at
point of output; update the rendering in the loop that consumes
get_quick_actions() so each value is properly escaped: use esc_attr() for id and
target and title, esc_url() for the href, and esc_html() (or esc_html_e/esc_html
depending on context) for the label text when echoing $quick_action['id'],
$quick_action['target'], $quick_action['url'], $quick_action['label'] inside the
anchor; keep the existing keys and structure but wrap each echoed value with the
appropriate escaping function to satisfy WordPress coding standards.
- Line 753: The checkbox label is output unescaped via "<?php echo
$field['label']; ?>" which can expose XSS; update the span to echo the escaped
label using esc_html() for $field['label'] (i.e., replace the direct echo with
an escaped output of $field['label']), keeping the surrounding span and class
intact.
- Around line 555-565: Escape all outputs derived from $group when writing into
HTML attributes, IDs and inline JS to prevent injection and broken markup:
replace direct uses of $group['slug'] in id attributes and the onclick handler
(e.g., occurrences that build "<?php echo $group['slug']; ?>_toggle", "<?php
echo $group['slug']; ?>_chevron", "<?php echo $group['slug']; ?>_content" and
the plausibleToggleSection(...) call) with a properly escaped value (use
htmlspecialchars($group['slug'], ENT_QUOTES, 'UTF-8') for attribute/ID contexts
and use json_encode($group['slug']) or similar JS-escaping when embedding into
the onclick string), and also escape $group['label'] when rendering the visible
text (e.g., htmlspecialchars($group['label'], ENT_QUOTES, 'UTF-8')).
- Line 129: $current_tab is assigned directly from $_GET['tab'] without
sanitization; update the assignment to sanitize and validate it against the
allowed tab keys before use. Use a sanitized input (e.g., cast to string and run
through sanitize_text_field or equivalent) and check it exists in your tabs list
(the array used to render/lookup tabs, referenced where $current_tab is later
used) then fall back to 'general' if not valid; ensure you modify the code
around the $current_tab assignment and the validation uses the same allowed-tabs
array used elsewhere in the class.
- Line 587: The group label is echoed unescaped (<?php echo $group['label']; ?>)
which can introduce XSS; update the output to escape the label using esc_html()
when echoing $group['label']; also ensure the id attribute using $group['slug']
is escaped with esc_attr() to be safe (adjust the h3 rendering that references
$group['slug'] and $group['label'] accordingly).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 01a3e115-402b-4df8-af70-8e189615f3d3

📥 Commits

Reviewing files that changed from the base of the PR and between 850407c and b4aec4f.

📒 Files selected for processing (2)
  • package.json
  • src/Admin/Settings/API.php

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