Add WPFTP feedback export: Tools admin page + WP-CLI command - #3651
Conversation
Jetpack Forms' own CSV export leaves out the logged-in user who submitted each response, even though Jetpack captures it internally (display name, username, user ID) at submission time. This is needed to later match WordPress Facilitator Training Program survey respondents' reported roles against who actually enrolled in and completed the courses. Adds: - wp feedback export (WP-CLI): full export of Jetpack Forms feedback responses (every field Jetpack's own CSV export has) plus the logged-in user, joined by feedback post ID. - Tools > WPFTP Feedback: the same export from wp-admin, with a form picker, status filters, and a date range, for exporting without shell access. Gated behind the export capability, nonce-protected. Both share get_rows()/build_csv() in feedback-logged-in-user-export.php; the CLI command lives in its own file per this plugin's convention of not mixing function declarations and class declarations in one file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an alternative export path for Jetpack Forms feedback responses in wporg-learn, ensuring each response row includes the logged-in user information Jetpack captures but does not include in its own CSV export.
Changes:
- Adds shared export logic (
get_rows()+build_csv()) to assemble Jetpack’s export columns and join logged-in user data by feedback post ID. - Adds a Tools → WPFTP Feedback admin page to download the CSV with form/status/date filters.
- Adds a
wp feedback exportWP-CLI subcommand to generate and save the same CSV.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| wp-content/plugins/wporg-learn/wporg-learn.php | Loads the new feedback export and WP-CLI command files. |
| wp-content/plugins/wporg-learn/inc/feedback-logged-in-user-export.php | Implements shared row building + CSV creation, and adds the Tools page + admin-post handler. |
| wp-content/plugins/wporg-learn/inc/class-feedback-export-cli.php | Registers the wp feedback export WP-CLI command using the shared export logic. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- wp_die()'s second argument is the title, not a status code — pass 403 via $args['response'] instead so the response actually sends that status. - get_rows() only checked Contact_Form_Plugin but immediately uses Feedback::POST_TYPE/Feedback::get(); check both classes exist. - render_admin_page() only checked Feedback, but the page also calls get_form_options() which needs Contact_Form_Plugin; check both. - Fall back to the Tools page URL when wp_get_referer() is empty, instead of redirecting to whatever admin-post.php happens to resolve to. - Add a screen-reader label for the unlabeled "before" date input. - Fix a grammatically garbled sentence in the CLI file's docblock. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Looking into it 👀 |
|
Update after merge: this was reverted in #3660 and re-landed with fixes in #3661. A full review of the merged code, checked against the Jetpack Forms source, the shared
One data caveat that matters for the role-to-completion analysis: Jetpack only began capturing the submitter's account in forms package 7.14.0 (23 March 2026). Responses stored before that have no The feature and its purpose are unchanged in #3661; @Piyopiyo-Kitsune is credited as co-author there. Thanks for building it. |
…3651)" (#3660) This reverts commit 14c2a19 (#3651). A review after the merge found defects that change what the export contains and CLI arguments that widen it instead of failing: - A Y-m-d date range drops both its boundary days. - The shared Export_CSV utility rewrites free-text answers (paragraph breaks collapsed, "<" encoded, percent sequences stripped, apostrophes inserted before " -", " +", " @", " ="). - An unrecognised --status exports every status including spam and trash, an unparseable --after exports everything, and a non-numeric --post means all forms. - The CLI writes the file, which holds usernames and IP addresses under a guessable name, into the current directory, the web root by default. Reverting so the corrected version can land as one clean change. Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Re-adds the Tools > WPFTP Feedback page and the `wp feedback export` command from #3651, reverted in #3660, with the post-merge review applied: - Date bounds are inclusive and must parse. - The CSV is written verbatim with fputcsv and Jetpack's own esc_csv() guard instead of the shared Export_CSV utility, which rewrote free text. - Status values are validated, --post must be numeric, and an all-test batch is an empty result rather than an error. - New columns: Status and "Logged-in user recorded" (Jetpack only began capturing the submitter in forms package 7.14.0); added columns carry Jetpack's space prefix so they cannot collide with form fields. - CLI: --dir is required and refused inside ABSPATH or WP_CONTENT_DIR, the file is created with 'x' and chmod 0600, the name carries the form and the time, and an empty result exits 0 with a warning. - A dedicated export_feedback_responses capability, granted to administrators, replaces core's export. - Responses are processed in batches of 200 with the Feedback cache cleared between them; the form picker covers every status and shows IDs. Co-authored-by: Destiny Kanno <17694715+Piyopiyo-Kitsune@users.noreply.github.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Context
The two WordPress Facilitator Training Program courses run a survey (a Jetpack Form) asking respondents what role they're in. Being able to later match who enrolled in and completed the course against their reported role requires knowing which logged-in user submitted each survey response.
Jetpack Forms' own CSV export doesn't include the logged-in user who submitted each response, even though Jetpack captures it internally (display name, username, user ID) at submission time. There's no filter/hook exposed by Jetpack to inject that into its own export, so this adds a standalone export path in wporg-learn instead.
What's added
wp feedback export(WP-CLI) — full export of Jetpack Forms feedback responses: every field Jetpack's own CSV export has (ID, Date, Title, Source, the form's own fields, Consent, IP Address, Country code, Browser), plus the logged-in user, joined by the real feedback post ID (not by row position).exportcapability (Administrator-only by default), nonce-protected.Both share
get_rows()/build_csv()infeedback-logged-in-user-export.php; the CLI command lives in its own file (class-feedback-export-cli.php) since this plugin's convention is not to mix function and class declarations in one file.Testing
phpcs.xml.dist./code-review(5 findings: reuse of Jetpack's ownget_all_parent_post_ids(), avoiding a redundant double-fetch of feedback data, replacing aconst+reassignment workaround with properuseimports, distinguishing integration failures from genuinely-empty results viaWP_Error, and comment-style) — all fixed and re-verified.🤖 Generated with Claude Code