Repository navigation
feat(logging): bulk download selected log entries as CSV - #865
Conversation
Adds a "Download Selected" bulk action to the logs list. Selected entries are streamed to php://output as a single CSV, fetched one at a time so memory stays flat, and capped by the filterable wpgraphql_logging_bulk_download_limit (default 1000). The single-entry download now shares the same header/stream/write code path.
📦 Plugin Artifacts Ready!Download from GitHub Actions run Available plugins:
See the "Artifacts" section at the bottom of the Actions run page |
Second review pass (correctness and security): - Escape cells that spreadsheets would evaluate as formulas. Log values such as the query and message come from unauthenticated GraphQL requests, so an exported CSV could otherwise run attacker formulas. - Drop open output buffers before streaming so large exports are not held in memory. - Ignore non-scalar IDs (absint() turns arrays into 1) and reuse the service's ID sanitizer in the list table.
…ge cases Third review pass (tests and static analysis): - Cover the ViewLogsPage load-time hook end to end: bad nonce and the 'Logs not found' path through the real database service. - Assert formula cells are escaped and plain cells are left alone. - Assert non-scalar IDs are dropped instead of becoming ID 1.
…le setup Fourth review pass (simplification, performance and docs): - Only build the list table at load time when the bulk download action is actually requested, instead of on every page load. - Document the Download Selected bulk action, the 1,000-row cap and its filters, and formula escaping in the plugin docs.
There was a problem hiding this comment.
🟡 Changes recommended
The output-buffer cleanup loop can run indefinitely when another plugin creates a non-removable buffer, causing single and bulk downloads to hang until the request times out.
1 open issue
What changed in this PR
Adds bulk CSV downloads to the logging plugin’s log list, addressing #405, and applies spreadsheet-formula escaping to both single and bulk exports.
Changes:
- Adds “Download Selected” with nonce validation and permission checks before CSV output.
- Streams selected logs into one CSV, with a configurable 1,000-entry limit.
- Adds unit and browser tests and documents bulk downloads and formula escaping.
| File | Description |
|---|---|
plugins/wpgraphql-logging/tests/wpunit/Admin/View/ViewLogsPageTest.php |
Tests bulk-download routing and nonce validation. |
plugins/wpgraphql-logging/tests/wpunit/Admin/View/List/ListTableTest.php |
Tests action registration and selected-ID handling. |
plugins/wpgraphql-logging/tests/wpunit/Admin/View/Download/DownloadLogServiceTest.php |
Tests CSV writing, permissions, ID limits, and formula escaping. |
plugins/wpgraphql-logging/tests/e2e/specs/bulk-download.spec.js |
Tests downloading selected logs through the admin interface. |
plugins/wpgraphql-logging/src/Admin/ViewLogsPage.php |
Dispatches bulk downloads before page rendering. |
plugins/wpgraphql-logging/src/Admin/View/List/ListTable.php |
Adds and handles the “Download Selected” action. |
plugins/wpgraphql-logging/src/Admin/View/Download/DownloadLogService.php |
Implements shared CSV streaming, bulk limits, and formula escaping. |
docs/plugins/wpgraphql-logging/index.md |
Documents bulk downloads, configuration filters, and CSV safety. |
Review effort: Balanced
…en a buffer is not removable' Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@copilot resolve the merge conflicts in this pull request |
…nload # Conflicts: # plugins/wpgraphql-logging/src/Admin/View/List/ListTable.php Co-authored-by: josephfusco <6676674+josephfusco@users.noreply.github.com>
Resolved in cca6d4e by merging |

Adds a "Download Selected" bulk action that streams the selected log entries as one CSV. Cells that a spreadsheet would run as formulas are now escaped in every download.
Closes #405
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Assisting with implementing bulk log downloads.