Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
CLI
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
72
0.00% covered (danger)
0.00%
0 / 1
 export
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2/**
3 * WP-CLI commands for Jetpack Forms.
4 *
5 * @package automattic/jetpack-forms
6 */
7
8namespace Automattic\Jetpack\Forms;
9
10use Automattic\Jetpack\Forms\ContactForm\Contact_Form_Plugin;
11use WP_CLI;
12use WP_CLI_Command;
13
14if ( ! class_exists( 'WP_CLI_Command' ) ) {
15    return;
16}
17
18/**
19 * Manage Jetpack Forms responses.
20 */
21class CLI extends WP_CLI_Command {
22    /**
23     * Export form responses as CSV, in the same format as the dashboard's CSV download.
24     *
25     * Responses are read in small batches, so this works however many a site has.
26     *
27     * ## OPTIONS
28     *
29     * [--file=<path>]
30     * : Write the CSV to this file instead of standard output.
31     *
32     * [--form=<post-id>]
33     * : Only export responses to the form with this ID. For older forms saved inside a post, use that post's ID. To filter by the page a response came from, use --source.
34     *
35     * [--status=<status>]
36     * : Which folder to export.
37     * ---
38     * default: inbox
39     * options:
40     *   - inbox
41     *   - spam
42     *   - trash
43     * ---
44     *
45     * [--search=<term>]
46     * : Only export responses matching this search term.
47     *
48     * [--after=<date>]
49     * : Only export responses received after this date, e.g. 2026-01-31.
50     *
51     * [--before=<date>]
52     * : Only export responses received before this date.
53     *
54     * [--source=<post-id>]
55     * : Only export responses submitted from this post or page.
56     *
57     * [--include-test]
58     * : Include test responses submitted from the form preview.
59     *
60     * ## EXAMPLES
61     *
62     *     wp jetpack-forms export --file=responses.csv
63     *     wp jetpack-forms export --form=123 --after=2026-01-01 > responses.csv
64     *
65     * @param array $args       Positional arguments.
66     * @param array $assoc_args Associative arguments.
67     */
68    public function export( $args, $assoc_args ) {
69        $plugin = Contact_Form_Plugin::init();
70
71        foreach ( array( 'after', 'before' ) as $bound ) {
72            if ( isset( $assoc_args[ $bound ] ) && ! strtotime( $assoc_args[ $bound ] ) ) {
73                WP_CLI::error( sprintf( 'Invalid --%s date: %s', $bound, $assoc_args[ $bound ] ) );
74            }
75        }
76
77        $feedback_ids = $plugin->get_export_feedback_ids(
78            array(
79                'form'   => (int) ( $assoc_args['form'] ?? 0 ),
80                'status' => $assoc_args['status'] ?? 'inbox',
81                'search' => $assoc_args['search'] ?? '',
82                'after'  => $assoc_args['after'] ?? '',
83                'before' => $assoc_args['before'] ?? '',
84                'source' => (int) ( $assoc_args['source'] ?? 0 ),
85            )
86        );
87
88        $rows = $plugin->get_export_rows( $feedback_ids, (bool) WP_CLI\Utils\get_flag_value( $assoc_args, 'include-test', false ) );
89        if ( ! $rows->valid() ) {
90            WP_CLI::warning( 'No responses match.' );
91            return;
92        }
93
94        $file = $assoc_args['file'] ?? null;
95        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
96        $output = null === $file ? STDOUT : fopen( $file, 'w' );
97        if ( false === $output ) {
98            WP_CLI::error( sprintf( 'Could not open %s for writing.', $file ) );
99        }
100
101        $count = $plugin->write_export_csv( $output, $rows );
102
103        if ( null !== $file ) {
104            fclose( $output ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
105            WP_CLI::success( sprintf( 'Exported %d responses to %s.', $count, $file ) );
106        }
107    }
108}