Skip to content

Release - #2927

Open
selul wants to merge 11 commits into
masterfrom
development
Open

Release#2927
selul wants to merge 11 commits into
masterfrom
development

Conversation

@selul

@selul selul commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Linked issues

This release will close the following issues once merged:

Public changelog

  • Form submissions can now be exported as a CSV file, with the export button offering a choice between CSV and XML formats.

Copilot AI review requested due to automatic review settings July 28, 2026 11:40
@pirate-bot

Copy link
Copy Markdown
Contributor

Bundle Size Diff

Package Old Size New Size Diff
Animations 178.33 KB 178.33 KB 0 B (0.00%)
Blocks 1.65 MB 1.65 MB 0 B (0.00%)
CSS 7.83 KB 7.83 KB 0 B (0.00%)
Dashboard 172.49 KB 172.49 KB 0 B (0.00%)
Onboarding 68.14 KB 68.14 KB 0 B (0.00%)
Export Import 4.73 KB 4.73 KB 0 B (0.00%)
Pro 439.82 KB 439.82 KB 0 B (0.00%)

Copilot AI 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.

Pull request overview

Adds CSV export support for stored form submissions while preserving WordPress XML as the default.

Changes:

  • Adds CSV generation and format selection.
  • Introduces an accessible export-format dropdown.
  • Expands unit and E2E export coverage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
inc/plugins/class-form-records-export.php Generates XML or CSV exports.
inc/plugins/class-dashboard.php Adds the export-format UI and download handling.
tests/test-form-submissions.php Tests XML defaults and CSV output.
src/blocks/test/e2e/blocks/form.spec.js Tests XML and CSV downloads.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +121 to +123
if ( ! isset( $input_columns[ $label ] ) ) {
$input_columns[ $column_key ] = $label;
}
Comment on lines +127 to +131
if ( 'file' === $input['type'] && isset( $input['metadata']['name'] ) ) {
$value = $input['metadata']['name'];
}

$row[ $column_key ] = $value;
Comment on lines +831 to +834
item.addEventListener('click', () => {
runExport(item.dataset.format);
closeMenu();
});
Comment on lines +892 to +895
$this->assertStringContainsString( 'Name', $output );
$this->assertStringContainsString( 'Company', $output );
$this->assertStringContainsString( 'Ada Lovelace', $output );
$this->assertStringContainsString( 'Analytical Engines Ltd', $output );
@pirate-bot

pirate-bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Plugin build for d972bbb is ready 🛎️!

@pirate-bot

pirate-bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

E2E Tests

Playwright Test Status: See serial and parallel matrix jobs

Performance Results serverResponse: {"q25":365.9,"q50":388.95,"q75":402.7,"cnt":10}, firstPaint: {"q25":1515.3,"q50":1547.65,"q75":1731.9,"cnt":10}, domContentLoaded: {"q25":3703.2,"q50":3716.15,"q75":3771.7,"cnt":10}, loaded: {"q25":3705.1,"q50":3718.25,"q75":3774,"cnt":10}, firstContentfulPaint: {"q25":4185.1,"q50":4216.45,"q75":4274.8,"cnt":10}, firstBlock: {"q25":14806.1,"q50":14965,"q75":15176.7,"cnt":10}, type: {"q25":29.96,"q50":32.67,"q75":36.4,"cnt":10}, typeWithoutInspector: {"q25":28.54,"q50":30.03,"q75":31.99,"cnt":10}, typeWithTopToolbar: {"q25":37.39,"q50":38.83,"q75":41.02,"cnt":10}, typeContainer: {"q25":17.7,"q50":20.1,"q75":22.14,"cnt":10}, focus: {"q25":149.76,"q50":154.89,"q75":158.23,"cnt":10}, inserterOpen: {"q25":45.41,"q50":48.09,"q75":50.91,"cnt":10}, inserterSearch: {"q25":16.89,"q50":19.37,"q75":20.17,"cnt":10}, inserterHover: {"q25":7.02,"q50":7.65,"q75":8.21,"cnt":20}, loadPatterns: {"q25":1885.14,"q50":1935.61,"q75":2032.79,"cnt":10}, listViewOpen: {"q25":249.85,"q50":272.77,"q75":281.31,"cnt":10}

Copilot AI review requested due to automatic review settings July 29, 2026 08:35

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (6)

inc/plugins/class-form-records-export.php:116

  • This second fputcsv() call also relies on the escape default deprecated in PHP 8.4, potentially emitting a deprecation into the download. Supply the escape parameter explicitly here as well.
				$output->fputcsv( $line );

inc/plugins/class-dashboard.php:834

  • After a keyboard user activates a format option, closeMenu() hides the element that still owns focus, leaving focus inside hidden content. Move focus back to the toggle after closing the menu so keyboard and screen-reader navigation resumes at a visible control.
					item.addEventListener('click', () => {
						runExport(item.dataset.format);
						closeMenu();
					});

inc/plugins/class-dashboard.php:806

  • Response.text() decodes and consumes the UTF-8 BOM written by the CSV exporter, so rebuilding the download from that string drops the BOM and defeats the Excel encoding safeguard. Keep the response as bytes (for example, via response.blob()) before assigning the CSV MIME type.
							const isCsv = 'csv' === format;
							const blob = new Blob([response], {type: isCsv ? 'text/csv;charset=utf-8' : 'text/xml'});

inc/plugins/class-form-records-export.php:284

  • Truncating the post ID makes the exported ID inaccurate once a site reaches IDs above eight digits and can create collisions between submissions. The record ID should be exported in full.
			'id'     => substr( strval( $record->ID ), -8 ),

inc/plugins/class-form-records-export.php:322

  • This key collapses every input sharing a label. In particular, a multiple-file field stores one input per uploaded file with the same label (src/blocks/frontend/form/index.js:103-118), so each assignment overwrites the previous filename and the CSV silently exports only the last file. Preserve repeated values by aggregating them or by using/disambiguating the stored input IDs.
			$parsed[ 'input:' . $input['label'] ] = array(
				'label' => $input['label'],
				'value' => $value,
			);

inc/plugins/class-form-records-export.php:102

  • PHP 8.4 deprecates relying on fputcsv()'s default escape parameter; with displayed deprecations this can also corrupt the generated CSV before its header. Pass an explicit empty escape string, which is supported by the project's PHP 7.4 minimum and produces standards-compliant CSV escaping.

This issue also appears on line 116 of the same file.

		$output->fputcsv( array_map( array( $this, 'sanitize_cell' ), array_values( $columns ) ) );

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.

[Experimental] Form Submissions "Export" outputs WordPress WXR XML, not the CSV stated in the changelog

4 participants