PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 2.0.3
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v2.0.3
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / includes / export / class-evf-entry-csv-exporter.php
everest-forms / includes / export Last commit date
abstract-evf-csv-exporter.php 5 years ago class-evf-entry-csv-exporter.php 3 years ago
class-evf-entry-csv-exporter.php
492 lines
1 <?php
2 /**
3 * Handles entry CSV export.
4 *
5 * @package EverestForms\Export
6 * @since 1.3.0
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 /**
12 * Include dependencies.
13 */
14 if ( ! class_exists( 'EVF_CSV_Exporter', false ) ) {
15 require_once EVF_ABSPATH . 'includes/export/abstract-evf-csv-exporter.php';
16 }
17
18 /**
19 * EVF_Entry_CSV_Exporter Class.
20 */
21 class EVF_Entry_CSV_Exporter extends EVF_CSV_Exporter {
22
23 /**
24 * Form ID.
25 *
26 * @var int|mixed
27 */
28 public $form_id;
29
30 /**
31 * Request Data.
32 *
33 * @since 1.8.7
34 * @var array
35 */
36 public $request_data;
37
38 /**
39 * Entry ID.
40 *
41 * @var int|mixed
42 */
43 public $entry_id;
44
45 /**
46 * Type of export used in filter names.
47 *
48 * @var string
49 */
50 protected $export_type = 'entry';
51
52 /**
53 * Constructor.
54 *
55 * @param int $form_id Form ID.
56 * @param int $entry_id Entry ID.
57 * @param array $request_data Request Data.
58 */
59 public function __construct( $form_id = '', $entry_id = '', $request_data = array() ) {
60 $this->form_id = absint( $form_id );
61 $this->entry_id = absint( $entry_id );
62 $this->request_data = $request_data;
63 $this->column_names = $this->get_default_column_names();
64 }
65
66 /**
67 * Return an array of columns to export.
68 *
69 * @return array
70 */
71 public function get_default_column_names() {
72 $columns = array();
73 $form_obj = evf()->form->get( $this->form_id );
74 $form_data = ! empty( $form_obj->post_content ) ? evf_decode( $form_obj->post_content ) : '';
75
76 // Set Entry ID at first.
77 $columns['entry_id'] = esc_html__( 'ID', 'everest-forms' );
78
79 // Add whitelisted fields to export columns.
80 if ( ! empty( $form_data['form_fields'] ) ) {
81 foreach ( $form_data['form_fields'] as $field ) {
82 if ( ! in_array( $field['type'], array( 'html', 'title', 'captcha', 'divider' ), true ) ) {
83 $columns[ $field['id'] ] = evf_clean( $field['label'] );
84 }
85 }
86 }
87
88 // Set the default columns.
89 $columns['status'] = esc_html__( 'Status', 'everest-forms' );
90 $columns['date_created'] = esc_html__( 'Date Created', 'everest-forms' );
91 $columns['date_created_gmt'] = esc_html__( 'Date Created GMT', 'everest-forms' );
92
93 // If user details are disabled globally discard the IP and UA.
94 if ( 'yes' !== get_option( 'everest_forms_disable_user_details' ) ) {
95 $columns['user_device'] = esc_html__( 'User Device', 'everest-forms' );
96 $columns['user_ip_address'] = esc_html__( 'User IP Address', 'everest-forms' );
97 }
98
99 return apply_filters( "everest_forms_export_{$this->export_type}_default_columns", $columns, $this->request_data );
100 }
101
102 /**
103 * Prepare data for export.
104 *
105 * @since 1.6.0
106 */
107 public function prepare_data_to_export() {
108 $this->row_data = array();
109
110 if ( $this->entry_id ) {
111 $entry = evf_get_entry( $this->entry_id );
112 $this->row_data[] = $this->generate_row_data( $entry );
113 } else {
114 $entry_ids = evf_search_entries(
115 array(
116 'limit' => -1,
117 'order' => 'ASC',
118 'form_id' => $this->form_id,
119 )
120 );
121
122 // Get the entries.
123 $entries = array_map( 'evf_get_entry', $entry_ids );
124 $checked_entry_id = isset( $_REQUEST['entry'] ) ? wp_parse_id_list( wp_unslash( $_REQUEST['entry'] ) ) : array(); // phpcs:ignore WordPress.Security.NonceVerification
125 foreach ( $entries as $entry ) {
126
127 if ( ! empty( $checked_entry_id ) && ! in_array( absint( $entry->entry_id ), $checked_entry_id, true ) ) {
128 continue;
129 }
130
131 $this->row_data[] = $this->generate_row_data( $entry );
132 }
133 }
134
135 return $this->row_data;
136 }
137
138 /**
139 * Prepare and get quiz report data in CSV format.
140 */
141 public function get_quiz_report() {
142 $form_data = EVF()->form->get(
143 absint( $this->form_id ),
144 array(
145 'content_only' => true,
146 )
147 );
148 $form_fields = isset( $form_data['form_fields'] ) ? $form_data['form_fields'] : array();
149 $entry = evf_get_entry( $this->entry_id );
150 $columns = array( 'ID' );
151 $row = array( $this->entry_id );
152 $total_score = 0;
153 $respondent_score = 0;
154 $obtained_score = 0;
155 $include_all_fields = apply_filters( 'evf_include_all_fields_in_quiz_report_csv', false );
156
157 // Add form fields in the CSV content.
158 foreach ( $form_fields as $field_id => $field ) {
159 $quiz_enabled = isset( $field['quiz_status'] ) && '1' === $field['quiz_status'] ? true : false;
160
161 // Move onto next field if this field has quiz disabled and non-quiz fields are to be excluded.
162 if ( false === $include_all_fields && false === $quiz_enabled ) {
163 continue;
164 }
165
166 $meta_key = isset( $field['meta-key'] ) ? $field['meta-key'] : '';
167 $given_answer = isset( $entry->meta[ $meta_key ] ) ? $entry->meta[ $meta_key ] : null;
168 $correct_answer = isset( $field['correct_answer'] ) ? $field['correct_answer'] : array();
169 $field_score = empty( $field['score'] ) ? 0 : $field['score'];
170 $score = 0;
171 $total_score += $field_score;
172 $is_correct = false;
173
174 if ( ! is_null( $given_answer ) ) {
175 $respondent_score += $field_score;
176
177 if ( ! empty( $correct_answer ) ) {
178 // Determine if the given answer is correct.
179 if ( 'select' === $field['type'] ) {
180 foreach ( $correct_answer as $answer_key => $answer_status ) {
181 $choice = $field['choices'][ $answer_key ]['label'];
182
183 if ( $given_answer === $choice ) {
184 $is_correct = true;
185 break;
186 }
187 }
188 } elseif ( 'radio' === $field['type'] ) {
189 $correct_answer_key = array_keys( $correct_answer )[0];
190 $correct_answer = $field['choices'][ $correct_answer_key ]['label'];
191 $given_answer = maybe_unserialize( $given_answer )['label'];
192 $is_correct = ( $given_answer === $correct_answer );
193 } elseif ( 'checkbox' === $field['type'] ) {
194 $given_answer_data = maybe_unserialize( $given_answer )['label'];
195 $is_correct = true;
196 $choices = $field['choices'];
197 $correct_answer_keys = array_keys( $correct_answer );
198 $correct_answers = array();
199 $given_answers = array();
200
201 // Prepare list of correct answers.
202 foreach ( $correct_answer_keys as $correct_answer_key ) {
203 $correct_answers[] = $choices[ $correct_answer_key ]['label'];
204 }
205
206 // Prepare list of given answers.
207 foreach ( $given_answer_data as $given_answer ) {
208 $given_answers[] = $given_answer;
209 }
210
211 // See if all the given answers are correct answers.
212 foreach ( $given_answers as $given_answer ) {
213 if ( ! in_array( $given_answer, $correct_answers, true ) ) {
214 $is_correct = false;
215 break;
216 }
217 }
218 }
219 }
220 }
221
222 // Add score if the given answer is correct.
223 if ( true === $is_correct ) {
224 $score = $field_score;
225 $obtained_score += $field_score;
226 }
227
228 $columns[] = $this->sanitize_csv_cell_data( $field['label'] );
229 $row[] = $this->sanitize_csv_cell_data( $score );
230 }
231
232 // Add extra columns.
233 $extra_data = array(
234 'Total Score' => $total_score,
235 'Respondent Score' => $respondent_score,
236 'Obtained Score' => $obtained_score,
237 );
238 foreach ( $extra_data as $key => $value ) {
239 $columns[] = $this->sanitize_csv_cell_data( $key );
240 $row[] = $this->sanitize_csv_cell_data( $value );
241 }
242
243 ob_start();
244 echo esc_html( implode( ', ', $columns ) );
245 echo "\n";
246 echo esc_html( implode( ', ', $row ) );
247
248 return ob_get_clean();
249 }
250
251 /**
252 * Sanitize data for a cell in CSV.
253 *
254 * @param string $str Data to sanitize.
255 */
256 public function sanitize_csv_cell_data( $str ) {
257 $str = (string) $str;
258 $str = str_replace( '"', '""', $str );
259 $str = '"' . $str . '"';
260 return $str;
261 }
262
263 /**
264 * Take a entry id and generate row data from it for export.
265 *
266 * @param object $entry Entry object.
267 * @return array
268 */
269 protected function generate_row_data( $entry ) {
270
271 $columns = $this->get_column_names();
272 $row = array();
273 $fields = json_decode( $entry->fields, true );
274 foreach ( $columns as $column_id => $column_name ) {
275 $column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id;
276 $value = '';
277 $raw_value = '';
278
279 if ( isset( $fields[ $column_id ] ) ) {
280 // Filter for entry meta data.
281 $field_type = isset( $fields[ $column_id ]['type'] ) ? $fields[ $column_id ]['type'] : '';
282
283 switch ( $field_type ) {
284 case 'checkbox':
285 case 'payment-checkbox':
286 $value = isset( $fields[ $column_id ]['value']['label'] ) ? $fields[ $column_id ]['value']['label'] : '';
287 if ( is_array( $value ) ) {
288 $value = implode( ',', $value );
289 } else {
290 $value = $value;
291 }
292 break;
293 case 'radio':
294 case 'payment-multiple':
295 $value = $fields[ $column_id ]['value']['label'];
296 break;
297 case 'select':
298 $value = $fields[ $column_id ]['value'];
299 if ( is_array( $value ) ) {
300 $value = implode( ',', $value );
301 } else {
302 $value = $value;
303 }
304
305 break;
306 case 'rating':
307 $value = ! empty( $fields[ $column_id ]['value']['value'] ) ? $fields[ $column_id ]['value']['value'] : 0;
308 $number_of_stars = ! empty( $fields[ $column_id ]['number_of_rating'] ) ? $fields[ $column_id ]['number_of_rating'] : 5;
309 $value = $value . '/' . $number_of_stars;
310 break;
311 case 'country':
312 $value = apply_filters( 'everest_forms_plaintext_field_value', $fields[ $column_id ]['value']['country_code'], $fields[ $column_id ]['value'], $entry, 'email-plain' );
313 break;
314 case 'repeater-fields':
315 $labels = array();
316 $repeater_fields = array();
317
318 foreach ( $fields[ $column_id ]['value_raw'] as $field_value ) {
319 foreach ( $field_value as $key => $val ) {
320 $repeater_field_value = '';
321 if ( isset( $repeater_fields[ $val['id'] ] ) ) {
322 $repeater_field_type = isset( $repeater_fields[ $val['id'] ]['type'] ) ? $repeater_fields[ $val['id'] ]['type'] : '';
323 switch ( $repeater_field_type ) {
324 case 'checkbox':
325 case 'payment-checkbox':
326 $value = $val['value']['label'];
327 $value = implode( ', ', $value );
328 $repeater_field_value = implode( ', ', $repeater_fields[ $val['id'] ]['value']['label'] );
329 $repeater_field_value .= ', ' . $value;
330 break;
331 case 'radio':
332 case 'payment-multiple':
333 $repeater_field_value = $repeater_fields[ $val['id'] ]['value']['label'];
334 $repeater_field_value .= ', ' . $val['value']['label'];
335 break;
336 case 'select':
337 $value = $val['value'];
338 if ( is_array( $value ) ) {
339 $value = implode( ',', $value );
340 } else {
341 $value = $value;
342 }
343 $repeater_field_value = implode( ', ', $repeater_fields[ $val['id'] ]['value'] );
344 $repeater_field_value .= ', ' . $value;
345 break;
346 default:
347 $repeater_field_value = $repeater_fields[ $val['id'] ]['value'];
348 $repeater_field_value .= ', ' . $val['value'];
349 break;
350 }
351 } else {
352 $repeater_fields[ $val['id'] ] = $val;
353 }
354 $fields[ $key ]['value'] = $repeater_field_value;
355 $labels [] = isset( $val['name'] ) ? $val['name'] : $val['value']['name'];
356
357 }
358 }
359
360 $labels = array_unique( $labels );
361 $value = '';
362
363 foreach ( $labels as $val ) {
364 if ( end( $labels ) === $val ) {
365 $value .= $val;
366 } else {
367 $value .= $val . ' ,';
368 }
369 }
370 break;
371 default:
372 $value = apply_filters( 'everest_forms_html_field_value', $fields[ $column_id ]['value'], $fields[ $column_id ], $entry, 'export-csv' );
373 break;
374 }
375 } elseif ( is_callable( array( $this, "get_column_value_{$column_id}" ) ) ) {
376 // Handle special columns which don't map 1:1 to entry data.
377 $value = $this->{"get_column_value_{$column_id}"}( $entry );
378 $raw_value = $value;
379 }
380 $column_type = $this->get_entry_type( $column_id, $entry );
381 $row[ $column_id ] = apply_filters( 'everest_forms_format_csv_field_data', preg_match( '/textarea/', $column_type ) ? sanitize_textarea_field( $value ) : sanitize_text_field( $value ), $raw_value, $column_id, $column_name, $columns, $entry );
382 $row['status'] = (
383 isset( $entry->meta['status'] ) && ! empty( $entry->meta['status'] )
384 ? $entry->meta['status']
385 : ( isset( $row['status'] ) ? $row['status'] : '' )
386 );
387 }
388
389 return apply_filters( 'everest_forms_entry_export_row_data', $row, $entry, $this->request_data );
390 }
391
392 /**
393 * Get entry type.
394 *
395 * @param string $column_id meta key of the column.
396 * @param object $entry Entry being exported.
397 * @return string
398 */
399 protected function get_entry_type( $column_id, $entry ) {
400 $fields = json_decode( $entry->fields, 1 );
401 if ( is_null( $fields ) || ! is_array( $fields ) ) {
402 return false; // Conditional false with fake values.
403 }
404 foreach ( $fields as $field ) {
405 if ( $column_id === $field['id'] ) {
406 return $field['type'];
407 }
408 }
409 return false;
410 }
411
412 /**
413 * Get entry id value.
414 *
415 * @param object $entry Entry being exported.
416 * @return int
417 */
418 protected function get_column_value_entry_id( $entry ) {
419 return absint( $entry->entry_id );
420 }
421
422 /**
423 * Get entry status value.
424 *
425 * @param object $entry Entry being exported.
426 * @return string
427 */
428 protected function get_column_value_status( $entry ) {
429 $statuses = evf_get_entry_statuses();
430
431 if ( isset( $statuses[ $entry->status ] ) ) {
432 return $statuses[ $entry->status ];
433 }
434
435 return $entry->status;
436 }
437
438 /**
439 * Get date created value.
440 *
441 * @param object $entry Entry being exported.
442 * @return string
443 */
444 protected function get_column_value_date_created( $entry ) {
445 $timestamp = false;
446
447 if ( isset( $entry->date_created ) ) {
448 $timestamp = strtotime( $entry->date_created );
449 }
450
451 /* translators: 1: entry date 2: entry time */
452 return sprintf( esc_html__( '%1$s %2$s', 'everest-forms' ), date_i18n( evf_date_format(), $timestamp ), date_i18n( evf_time_format(), $timestamp ) );
453 }
454
455 /**
456 * Get GMT date created value.
457 *
458 * @param object $entry Entry being exported.
459 * @return string
460 */
461 protected function get_column_value_date_created_gmt( $entry ) {
462 $timestamp = false;
463
464 if ( isset( $entry->date_created ) ) {
465 $timestamp = strtotime( $entry->date_created ) + ( get_option( 'gmt_offset' ) * 3600 );
466 }
467
468 /* translators: 1: entry date 2: entry time */
469 return sprintf( esc_html__( '%1$s %2$s', 'everest-forms' ), date_i18n( evf_date_format(), $timestamp ), date_i18n( evf_time_format(), $timestamp ) );
470 }
471
472 /**
473 * Get entry user device value.
474 *
475 * @param object $entry Entry being exported.
476 * @return string
477 */
478 protected function get_column_value_user_device( $entry ) {
479 return sanitize_text_field( $entry->user_device );
480 }
481
482 /**
483 * Get entry user IP address value.
484 *
485 * @param object $entry Entry being exported.
486 * @return string
487 */
488 protected function get_column_value_user_ip_address( $entry ) {
489 return sanitize_text_field( $entry->user_ip_address );
490 }
491 }
492