Database Row
Each submission is stored as a row in wp_formforge_submissions. The data column contains a JSON-encoded string of all submitted field values.
Decoded data Field
Each key in the decoded data object is the field ID. Each value has label, value, and type:
{
"field_1": {
"label": "Full Name",
"value": "John Doe",
"type": "text"
},
"field_2": {
"label": "Email",
"value": "[email protected]",
"type": "email"
}
}Value Formats by Field Type
| Field Type | Value Format | Example |
|---|---|---|
text, email, phone, url | Plain string | "John Doe" |
textarea | String (may contain newlines) | "Line 1nLine 2" |
number | Numeric string | "42" |
select, radio | Selected option value | "sales" |
checkbox (single) | "1" or "" | "1" |
checkbox (multiple) | JSON array string | "["option1","option2"]" |
date | ISO date string | "2025-03-15" |
rating | Numeric string (1-N) | "4" |
file_upload | URL to uploaded file | "https://example.com/.../resume.pdf" |
map_address | JSON-encoded location | "{"address":"...","lat":"40.7"}" |
payment | PaymentIntent ID | "pi_3N1234567890" |
repeater | JSON-encoded array | "[{"name":"Row 1"}]" |
Stored values preserve enough structure for integrations, but user-facing surfaces should not print the raw storage form. Use FORMFORGE_Value_Formatter::submission_display_fields() or FORMFORGE_Value_Formatter::text() when rendering emails, Slack/Discord/Telegram messages, CSV/PDF rows, submission modals, or post-submission content. The formatter converts scalar checkbox values to readable labels, groups repeater rows, formats date/calendar values with the WordPress site format, masks passwords, skips empty hidden/system fields, de-duplicates map coordinates, and appends Payment status / amount / date / ID rows from _payment.
Querying Submissions in PHP
global $wpdb;
$table = $wpdb->prefix . 'formforge_submissions';
$submissions = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM {$table} WHERE form_id = %d ORDER BY created_at DESC LIMIT 100",
42
) );
foreach ( $submissions as $sub ) {
$data = json_decode( $sub->data, true );
$name = $data['field_1']['value'] ?? '';
$email = $data['field_2']['value'] ?? '';
echo "Submission #{$sub->id}: {$name} ({$email})n";
}Exporting Submissions as CSV
function export_submissions_csv( $form_id ) {
global $wpdb;
$table = $wpdb->prefix . 'formforge_submissions';
$rows = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM {$table} WHERE form_id = %d AND status = 'new' ORDER BY created_at ASC",
$form_id
) );
if ( empty( $rows ) ) return '';
$output = fopen( 'php://temp', 'r+' );
$first_data = json_decode( $rows[0]->data, true );
$headers = [ 'ID', 'Date' ];
foreach ( $first_data as $field ) {
$headers[] = $field['label'];
}
fputcsv( $output, $headers );
foreach ( $rows as $row ) {
$data = json_decode( $row->data, true );
$line = [ $row->id, $row->created_at ];
foreach ( $data as $field ) {
$val = is_array( $field['value'] ) ? implode( ', ', $field['value'] ) : $field['value'];
$line[] = $val;
}
fputcsv( $output, $line );
}
rewind( $output );
$csv = stream_get_contents( $output );
fclose( $output );
return $csv;
}—