get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE form_id = %d ORDER BY created_at DESC", $form_id ) ); // phpcs:ignore WordPress.DB } else { $rows = $wpdb->get_results( "SELECT * FROM {$table} ORDER BY created_at DESC" ); // phpcs:ignore WordPress.DB } // Collect the union of all field labels for the header row. $labels = []; $parsed = []; foreach ( $rows as $row ) { $data = json_decode( $row->fields, true ); $data = is_array( $data ) ? $data : []; $parsed[] = [ 'row' => $row, 'data' => $data ]; foreach ( $data as $field ) { $label = isset( $field['label'] ) ? $field['label'] : ''; if ( '' !== $label && ! in_array( $label, $labels, true ) ) { $labels[] = $label; } } } $filename = 'phemightforms-entries-' . gmdate( 'Y-m-d' ) . '.csv'; nocache_headers(); header( 'Content-Type: text/csv; charset=utf-8' ); header( 'Content-Disposition: attachment; filename=' . $filename ); $out = fopen( 'php://output', 'w' ); fputcsv( $out, array_merge( [ __( 'ID', 'phemightforms' ), __( 'Date', 'phemightforms' ) ], $labels ) ); foreach ( $parsed as $item ) { $values = [ $item['row']->id, $item['row']->created_at ]; // Map this entry's values onto the shared label columns. $by_label = []; foreach ( $item['data'] as $field ) { if ( isset( $field['label'] ) ) { $by_label[ $field['label'] ] = isset( $field['value'] ) ? $field['value'] : ''; } } foreach ( $labels as $label ) { $values[] = isset( $by_label[ $label ] ) ? $by_label[ $label ] : ''; } fputcsv( $out, $values ); } fclose( $out ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose exit; } /** * Delete entries older than the configured retention window. */ public function cleanup() { $days = (int) Plugin::get_option( 'entry_retention_days', 0 ); if ( $days <= 0 ) { return; } global $wpdb; $table = Install::entries_table(); $cutoff = gmdate( 'Y-m-d H:i:s', time() - ( $days * DAY_IN_SECONDS ) ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE created_at < %s", $cutoff ) ); // phpcs:ignore WordPress.DB } /** * Build a nonce-protected export URL. * * @param int $form_id Optional form filter. * @return string */ public static function export_url( $form_id = 0 ) { return wp_nonce_url( add_query_arg( array_filter( [ 'action' => 'phemightforms_export', 'form' => $form_id, ] ), admin_url( 'admin-post.php' ) ), 'phemightforms_export' ); } }