PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 1.9.9
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v1.9.9
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 6 years ago class-evf-entry-csv-exporter.php 3 years ago
class-evf-entry-csv-exporter.php
452 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 $columns = $this->get_column_names();
271 $row = array();
272 $fields = json_decode( $entry->fields, true );
273 foreach ( $columns as $column_id => $column_name ) {
274 $column_id = strstr( $column_id, ':' ) ? current( explode( ':', $column_id ) ) : $column_id;
275 $value = '';
276 $raw_value = '';
277
278 if ( isset( $fields[ $column_id ] ) ) {
279 // Filter for entry meta data.
280 $field_type = isset( $fields[ $column_id ]['type'] ) ? $fields[ $column_id ]['type'] : '';
281
282 switch ( $field_type ) {
283 case 'checkbox':
284 case 'payment-checkbox':
285 $value = $fields[ $column_id ]['value']['label'];
286 $value = implode( ', ', $value );
287 break;
288 case 'radio':
289 case 'payment-multiple':
290 $value = $fields[ $column_id ]['value']['label'];
291 break;
292 case 'select':
293 $value = $fields[ $column_id ]['value'];
294 if ( is_array( $value ) ) {
295 $value = implode( ',', $value );
296 } else {
297 $value = $value;
298 }
299
300 break;
301 case 'rating':
302 $value = ! empty( $fields[ $column_id ]['value']['value'] ) ? $fields[ $column_id ]['value']['value'] : 0;
303 $number_of_stars = ! empty( $fields[ $column_id ]['number_of_rating'] ) ? $fields[ $column_id ]['number_of_rating'] : 5;
304 $value = $value . '/' . $number_of_stars;
305 break;
306 case 'country':
307 $value = apply_filters( 'everest_forms_plaintext_field_value', $fields[ $column_id ]['value']['country_code'], $fields[ $column_id ]['value'], $entry, 'email-plain' );
308 break;
309 case 'repeater-fields':
310 $labels = array();
311 $repeater_fields = array();
312
313 foreach ( $fields[ $column_id ]['value_raw'] as $field_value ) {
314 foreach ( $field_value as $key => $val ) {
315 if ( isset( $repeater_fields[ $val['id'] ] ) ) {
316 $repeater_fields[ $val['id'] ]['value'] .= ', ' . $val['value'];
317 } else {
318 $repeater_fields[ $val['id'] ] = $val;
319 }
320 $fields[ $key ]['value'] = $repeater_fields[ $val['id'] ]['value'];
321 $labels [] = $val['name'];
322 }
323 }
324
325 $labels = array_unique( $labels );
326 $value = '';
327
328 foreach ( $labels as $val ) {
329 if ( end( $labels ) === $val ) {
330 $value .= $val;
331 } else {
332 $value .= $val . ' ,';
333 }
334 }
335 break;
336 default:
337 $value = apply_filters( 'everest_forms_html_field_value', $fields[ $column_id ]['value'], $fields[ $column_id ], $entry, 'export-csv' );
338 break;
339 }
340 } elseif ( is_callable( array( $this, "get_column_value_{$column_id}" ) ) ) {
341 // Handle special columns which don't map 1:1 to entry data.
342 $value = $this->{"get_column_value_{$column_id}"}( $entry );
343 $raw_value = $value;
344 }
345 $column_type = $this->get_entry_type( $column_id, $entry );
346 $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 );
347 }
348
349 return apply_filters( 'everest_forms_entry_export_row_data', $row, $entry, $this->request_data );
350 }
351
352 /**
353 * Get entry type.
354 *
355 * @param string $column_id meta key of the column.
356 * @param object $entry Entry being exported.
357 * @return string
358 */
359 protected function get_entry_type( $column_id, $entry ) {
360 $fields = json_decode( $entry->fields, 1 );
361 if ( is_null( $fields ) || ! is_array( $fields ) ) {
362 return false; // Conditional false with fake values.
363 }
364 foreach ( $fields as $field ) {
365 if ( $column_id === $field['id'] ) {
366 return $field['type'];
367 }
368 }
369 return false;
370 }
371
372 /**
373 * Get entry id value.
374 *
375 * @param object $entry Entry being exported.
376 * @return int
377 */
378 protected function get_column_value_entry_id( $entry ) {
379 return absint( $entry->entry_id );
380 }
381
382 /**
383 * Get entry status value.
384 *
385 * @param object $entry Entry being exported.
386 * @return string
387 */
388 protected function get_column_value_status( $entry ) {
389 $statuses = evf_get_entry_statuses();
390
391 if ( isset( $statuses[ $entry->status ] ) ) {
392 return $statuses[ $entry->status ];
393 }
394
395 return $entry->status;
396 }
397
398 /**
399 * Get date created value.
400 *
401 * @param object $entry Entry being exported.
402 * @return string
403 */
404 protected function get_column_value_date_created( $entry ) {
405 $timestamp = false;
406
407 if ( isset( $entry->date_created ) ) {
408 $timestamp = strtotime( $entry->date_created );
409 }
410
411 /* translators: 1: entry date 2: entry time */
412 return sprintf( esc_html__( '%1$s %2$s', 'everest-forms' ), date_i18n( evf_date_format(), $timestamp ), date_i18n( evf_time_format(), $timestamp ) );
413 }
414
415 /**
416 * Get GMT date created value.
417 *
418 * @param object $entry Entry being exported.
419 * @return string
420 */
421 protected function get_column_value_date_created_gmt( $entry ) {
422 $timestamp = false;
423
424 if ( isset( $entry->date_created ) ) {
425 $timestamp = strtotime( $entry->date_created ) + ( get_option( 'gmt_offset' ) * 3600 );
426 }
427
428 /* translators: 1: entry date 2: entry time */
429 return sprintf( esc_html__( '%1$s %2$s', 'everest-forms' ), date_i18n( evf_date_format(), $timestamp ), date_i18n( evf_time_format(), $timestamp ) );
430 }
431
432 /**
433 * Get entry user device value.
434 *
435 * @param object $entry Entry being exported.
436 * @return string
437 */
438 protected function get_column_value_user_device( $entry ) {
439 return sanitize_text_field( $entry->user_device );
440 }
441
442 /**
443 * Get entry user IP address value.
444 *
445 * @param object $entry Entry being exported.
446 * @return string
447 */
448 protected function get_column_value_user_ip_address( $entry ) {
449 return sanitize_text_field( $entry->user_ip_address );
450 }
451 }
452