Completed
Push — master ( c5b2f2...93f4f3 )
by Stephanie
03:11
created

FrmEntryFormat::prepare_field_output()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
class FrmEntryFormat {
4
	public static function show_entry( $atts ) {
5
		$atts = shortcode_atts( array(
6
			'id' => false, 'entry' => false, 'fields' => false, 'plain_text' => false,
7
			'user_info' => false, 'include_blank' => false, 'default_email' => false,
8
			'form_id' => false, 'format' => 'text', 'direction' => 'ltr',
9
			'font_size' => '', 'text_color' => '',
10
			'border_width' => '', 'border_color' => '',
11
			'bg_color' => '', 'alt_bg_color' => '',
12
			'clickable' => false,
13
			'exclude_fields' => '', 'include_fields' => '',
14
			'include_extras' => '', 'inline_style' => 1,
15
		), $atts );
16
17
		$atts['exclude_fields'] = self::comma_list_to_array( $atts['exclude_fields'] );
18
		$atts['include_fields'] = self::comma_list_to_array( $atts['include_fields'] );
19
		$atts['include_extras'] = self::comma_list_to_array( $atts['include_extras'] );
20
21
		if ( $atts['format'] != 'text' ) {
22
			//format options are text, array, or json
23
			$atts['plain_text'] = true;
24
		}
25
26
		if ( is_object( $atts['entry'] ) && ! isset( $atts['entry']->metas ) ) {
27
			// if the entry does not include metas, force it again
28
			$atts['entry'] = false;
29
		}
30
31
		if ( ! $atts['entry'] || ! is_object( $atts['entry'] ) ) {
32
			if ( ! $atts['id'] && ! $atts['default_email'] ) {
33
				return '';
34
			}
35
36
			if ( $atts['id'] ) {
37
				$atts['entry'] = FrmEntry::getOne( $atts['id'], true );
38
			}
39
		}
40
41
		if ( $atts['entry'] ) {
42
			$atts['form_id'] = $atts['entry']->form_id;
43
			$atts['id'] = $atts['entry']->id;
44
		}
45
46
		if ( ! $atts['fields'] || ! is_array( $atts['fields'] ) ) {
47
			$atts['fields'] = FrmField::get_all_for_form( $atts['form_id'], '', 'include' );
48
		}
49
50
		$values = array();
51
		foreach ( $atts['fields'] as $f ) {
52
			if ( ! self::skip_field( $atts, $f ) ) {
53
				self::fill_entry_values( $atts, $f, $values );
54
			}
55
			unset($f);
56
		}
57
58
		self::fill_entry_user_info( $atts, $values );
59
		$values = apply_filters( 'frm_show_entry_array', $values, $atts );
60
61
		if ( $atts['format'] == 'json' ) {
62
			$content = json_encode( $values );
63
		} else if ( $atts['format'] == 'array' ) {
64
			$content = $values;
65
		} else {
66
			$content = array();
67
			self::prepare_text_output( $values, $atts, $content );
68
		}
69
70
		return $content;
71
	}
72
73
	private static function comma_list_to_array( $list ) {
74
		$array = array_map( 'strtolower', array_map( 'trim', explode( ',', $list ) ) );
75
		$field_types = array(
76
			'section' => 'divider',
77
			'heading' => 'divider',
78
			'page'    => 'break',
79
		);
80
		foreach ( $field_types as $label => $field_type ) {
81
			if ( in_array( $label, $array ) ) {
82
				$array[] = $field_type;
83
			}
84
		}
85
		return $array;
86
	}
87
88
	private static function skip_field( $atts, $field ) {
89
		$skip = ( $field->type == 'password' || $field->type == 'credit_card' );
90
91
		if ( $skip && ! empty( $atts['include_extras'] ) ) {
92
			$skip = ! in_array( $field->type, $atts['include_extras'] );
93
		}
94
95
		if ( ! $skip && ! empty( $atts['exclude_fields'] ) ) {
96
			$skip = self::field_in_list( $field, $atts['exclude_fields'] );
97
		}
98
99
		if ( $skip && ! empty( $atts['include_fields'] ) ) {
100
			$skip = ! self::field_in_list( $field, $atts['include_fields'] );
101
		}
102
103
		return $skip;
104
	}
105
106
	private static function field_in_list( $field, $list ) {
107
		return ( in_array( $field->id, $list ) || in_array( $field->field_key, $list ) );
108
	}
109
110
	/**
111
	 * Get the labels and value shortcodes for fields in the Default HTML email message
112
	 *
113
	 * @since 2.0.23
114
	 * @param object $f
115
	 * @param array $values
116
	 */
117
	public static function get_field_shortcodes_for_default_email( $f, &$values ) {
118
		$field_shortcodes = array(
119
			'label' => '[' . $f->id . ' show=field_label]',
120
			'val'   => '[' . $f->id . ']',
121
			'type'  => $f->type,
122
		);
123
124
		$values[ $f->id ] = apply_filters( 'frm_field_shortcodes_for_default_html_email', $field_shortcodes, $f );
125
	}
126
127
	public static function fill_entry_values( $atts, $f, array &$values ) {
128
		$no_save_field = FrmField::is_no_save_field( $f->type );
129
		if ( $no_save_field ) {
130
			if ( ! in_array( $f->type, $atts['include_extras'] ) ) {
131
				return;
132
			}
133
			$atts['include_blank'] = true;
134
		}
135
136
		if ( $atts['default_email'] ) {
137
			self::get_field_shortcodes_for_default_email( $f, $values );
138
			return;
139
		}
140
141
		$atts['field'] = $f;
142
143
		self::fill_missing_fields( $atts, $values );
144
145
		$val = '';
146
		self::get_field_value( $atts, $val );
147
148
		// Don't include blank values
149
		if ( ! $atts['include_blank'] && FrmAppHelper::is_empty_value( $val ) ) {
150
			return;
151
		}
152
153
		self::prepare_field_output( $atts, $val );
154
155
		if ( $atts['format'] != 'text' ) {
156
			$values[ $f->field_key ] = $val;
157
			if ( $atts['entry'] && $f->type != 'textarea' ) {
158
				$prev_val = maybe_unserialize( $atts['entry']->metas[ $f->id ] );
159
				if ( $prev_val != $val ) {
160
					$values[ $f->field_key . '-value' ] = $prev_val;
161
				}
162
			}
163
		} else {
164
			$values[ $f->id ] = array( 'label' => $f->name, 'val' => $val, 'type' => $f->type );
165
		}
166
	}
167
168
	private static function fill_missing_fields( $atts, &$values ) {
169
		if ( $atts['entry'] && ! isset( $atts['entry']->metas[ $atts['field']->id ] ) ) {
170
			// In case include_blank is set
171
			$atts['entry']->metas[ $atts['field']->id ] = '';
172
			$atts['entry'] = apply_filters( 'frm_prepare_entry_content', $atts['entry'], array( 'field' => $atts['field'] ) );
173
			self::fill_values_from_entry( $atts, $values );
174
		}
175
	}
176
177
	public static function fill_values_from_entry( $atts, &$values ) {
178
		$values = apply_filters( 'frm_prepare_entry_array', $values, $atts );
179
	}
180
181
	private static function get_field_value( $atts, &$val ) {
182
		$f = $atts['field'];
183
		if ( $atts['entry'] ) {
184
			$prev_val = maybe_unserialize( $atts['entry']->metas[ $f->id ] );
185
			$meta = array( 'item_id' => $atts['id'], 'field_id' => $f->id, 'meta_value' => $prev_val, 'field_type' => $f->type );
0 ignored issues
show
introduced by
Detected usage of meta_value, possible slow query.
Loading history...
186
187
			//This filter applies to the default-message shortcode and frm-show-entry shortcode only
188
			if ( in_array( $f->type, array( 'html', 'divider', 'break' ) ) ) {
189
				$val = apply_filters( 'frm_content', $f->description, $atts['form_id'], $atts['entry'] );
190
			} elseif ( isset( $atts['filter'] ) && $atts['filter'] == false ) {
191
				$val = $prev_val;
192
			} else {
193
				$val = apply_filters( 'frm_email_value', $prev_val, (object) $meta, $atts['entry'], compact( 'field' ) );
194
			}
195
		}
196
	}
197
198
	/**
199
	* Flatten multi-dimensional array for multi-file upload fields
200
	* @since 2.0.9
201
	*/
202
	public static function flatten_multi_file_upload( $field, &$val ) {
203
		if ( $field->type == 'file' && FrmField::is_option_true( $field, 'multiple' ) ) {
204
			$val = FrmAppHelper::array_flatten( $val );
205
		}
206
	}
207
208
	/**
209
	 * @since 2.03.02
210
	 */
211
	public static function prepare_field_output( $atts, &$val ) {
212
		self::textarea_display_value( $atts['field']->type, $atts['plain_text'], $val );
213
		$val = apply_filters( 'frm_display_' . $atts['field']->type . '_value_custom', $val, array(
214
			'field' => $atts['field'], 'atts' => $atts,
215
		) );
216
217
		self::flatten_array_value( $atts, $val );
218
		self::maybe_strip_html( $atts['plain_text'], $val );
219
	}
220
221
    /**
222
     * Replace returns with HTML line breaks for display
223
     * @since 2.0.9
224
     */
225
	public static function textarea_display_value( $type, $plain_text, &$value ) {
226
		if ( $type == 'textarea' && ! $plain_text ) {
227
			$value = str_replace( array( "\r\n", "\r", "\n" ), ' <br/>', $value );
228
		}
229
	}
230
231
	/**
232
	 * @since 2.03.02
233
	 */
234
	private static function flatten_array_value( $atts, &$val ) {
235
		if ( is_array( $val ) ) {
236
			if ( $atts['format'] == 'text' ) {
237
				$val = implode( ', ', $val );
238
			} else if ( $f->type == 'checkbox' ) {
0 ignored issues
show
Bug introduced by
The variable $f does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
239
				$val = array_values( $val );
240
			}
241
		}
242
	}
243
244
	/**
245
	 * Strip HTML if from email value if plain text is selected
246
	 *
247
	 * @since 2.0.21
248
	 * @param boolean $plain_text
249
	 * @param mixed $val
250
	 */
251
	private static function maybe_strip_html( $plain_text, &$val ) {
252
		if ( $plain_text && ! is_array( $val ) ) {
253
			if ( strpos( $val, '<img' ) !== false ) {
254
				$val = str_replace( array( '<img', 'src=', '/>', '"' ), '', $val );
255
				$val = trim( $val );
256
			}
257
			$val = strip_tags( $val );
258
		}
259
	}
260
261
	public static function fill_entry_user_info( $atts, array &$values ) {
262
		if ( ! $atts['user_info'] || empty( $atts['entry'] ) ) {
263
			return;
264
		}
265
266
		$data  = self::get_entry_description_data( $atts );
267
268
		if ( $atts['default_email'] ) {
269
			$atts['entry']->ip = '[ip]';
270
		}
271
272
		if ( $atts['format'] != 'text' ) {
273
			$values['ip'] = $atts['entry']->ip;
274
			$values['browser'] = self::get_browser( $data['browser'] );
275
			$values['referrer'] = $data['referrer'];
276
		} else {
277
			$values['ip'] = array( 'label' => __( 'IP Address', 'formidable' ), 'val' => $atts['entry']->ip );
278
			$values['browser'] = array(
279
				'label' => __( 'User-Agent (Browser/OS)', 'formidable' ),
280
				'val'   => self::get_browser( $data['browser'] ),
281
			);
282
			$values['referrer'] = array( 'label' => __( 'Referrer', 'formidable' ), 'val' => $data['referrer'] );
283
		}
284
	}
285
286
	/**
287
	 * @param array $atts - include (object) entry, (boolean) default_email
288
	 * @since 2.0.9
289
	 */
290
	public static function get_entry_description_data( $atts ) {
291
		$default_data = array(
292
			'browser' => '',
293
			'referrer' => '',
294
		);
295
		$data = $default_data;
296
297
		if ( isset( $atts['entry']->description ) ) {
298
			$data = (array) maybe_unserialize( $atts['entry']->description );
299
		} else if ( $atts['default_email'] ) {
300
			$data = array(
301
				'browser'  => '[browser]',
302
				'referrer' => '[referrer]',
303
			);
304
		}
305
306
		return array_merge( $default_data, $data );
307
	}
308
309
	public static function get_browser( $u_agent ) {
310
		$bname = __( 'Unknown', 'formidable' );
311
		$platform = __( 'Unknown', 'formidable' );
312
		$ub = '';
313
314
		// Get the operating system
315
		if ( preg_match( '/windows|win32/i', $u_agent ) ) {
316
			$platform = 'Windows';
317
		} else if ( preg_match( '/android/i', $u_agent ) ) {
318
			$platform = 'Android';
319
		} else if ( preg_match( '/linux/i', $u_agent ) ) {
320
			$platform = 'Linux';
321
		} else if ( preg_match( '/macintosh|mac os x/i', $u_agent ) ) {
322
			$platform = 'OS X';
323
		}
324
325
		$agent_options = array(
326
			'Chrome'   => 'Google Chrome',
327
			'Safari'   => 'Apple Safari',
328
			'Opera'    => 'Opera',
329
			'Netscape' => 'Netscape',
330
			'Firefox'  => 'Mozilla Firefox',
331
		);
332
333
		// Next get the name of the useragent yes seperately and for good reason
334
		if ( strpos( $u_agent, 'MSIE' ) !== false && strpos( $u_agent, 'Opera' ) === false ) {
335
			$bname = 'Internet Explorer';
336
			$ub = 'MSIE';
337
		} else {
338
			foreach ( $agent_options as $agent_key => $agent_name ) {
339
				if ( strpos( $u_agent, $agent_key ) !== false ) {
340
					$bname = $agent_name;
341
					$ub = $agent_key;
342
					break;
343
				}
344
			}
345
		}
346
347
		// finally get the correct version number
348
		$known = array( 'Version', $ub, 'other' );
349
		$pattern = '#(?<browser>' . join( '|', $known ) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
350
		preg_match_all( $pattern, $u_agent, $matches ); // get the matching numbers
351
352
		// see how many we have
353
		$i = count($matches['browser']);
354
		if ( $i != 1 ) {
355
			//we will have two since we are not using 'other' argument yet
356
			//see if version is before or after the name
357
			if ( strripos( $u_agent, 'Version' ) < strripos( $u_agent, $ub ) ) {
358
				$version = $matches['version'][0];
359
			} else {
360
				$version = $matches['version'][1];
361
			}
362
		} else {
363
			$version = $matches['version'][0];
364
		}
365
366
		// check if we have a number
367
		if ( $version == '' ) {
368
			$version = '?';
369
		}
370
371
		return $bname . ' ' . $version . ' / ' . $platform;
372
	}
373
374
	private static function prepare_text_output( $values, $atts, &$content ) {
375
		self::convert_entry_to_content( $values, $atts, $content );
376
377
		if ( 'text' == $atts['format'] ) {
378
			$content = implode('', $content);
379
		}
380
381
		if ( $atts['clickable'] ) {
382
			$content = make_clickable( $content );
383
		}
384
	}
385
386
	public static function convert_entry_to_content( $values, $atts, array &$content ) {
387
		if ( $atts['plain_text'] ) {
388
			self::plain_text_content( $values, $atts, $content );
389
		} else {
390
			self::html_content( $values, $atts, $content );
391
		}
392
	}
393
394
	private static function plain_text_content( $values, $atts, &$content ) {
395
		foreach ( $values as $id => $value ) {
396
			$atts['id'] = $id;
397
			$atts['value'] = $value;
398
			self::single_plain_text_row( $atts, $content );
399
		}
400
	}
401
402
	private static function html_content( $values, $atts, &$content ) {
403
		self::setup_defaults( $atts );
404
		self::prepare_inline_styles( $atts );
405
406
		$content[] = '<table cellspacing="0" ' . $atts['table_style'] . '><tbody>' . "\r\n";
407
408
		$atts['odd'] = true;
409
		foreach ( $values as $id => $value ) {
410
			$atts['id'] = $id;
411
			$atts['value'] = $value;
412
			self::single_html_row( $atts, $content );
413
			$atts['odd'] = ! $atts['odd'];
414
		}
415
416
		$content[] = '</tbody></table>';
417
	}
418
419
	private static function setup_defaults( &$atts ) {
420
		$default_settings = apply_filters( 'frm_show_entry_styles', array(
421
			'border_color' => 'dddddd',
422
			'bg_color'     => 'f7f7f7',
423
			'text_color'   => '444444',
424
			'font_size'    => '12px',
425
			'border_width' => '1px',
426
			'alt_bg_color' => 'ffffff',
427
		) );
428
429
		// merge defaults, global settings, and shortcode options
430
		foreach ( $default_settings as $key => $setting ) {
431
			if ( $atts[ $key ] != '' ) {
432
				continue;
433
			}
434
435
			$atts[ $key ] = $setting;
436
			unset( $key, $setting );
437
		}
438
	}
439
440
	private static function prepare_inline_styles( &$atts ) {
441
		if ( empty( $atts['inline_style'] ) ) {
442
			$atts['table_style'] = $atts['bg_color'] = $atts['bg_color_alt'] = $atts['row_style'] = '';
443
		} else {
444
			$atts['table_style'] = ' style="' . esc_attr( 'font-size:' . $atts['font_size'] . ';line-height:135%; border-bottom:' . $atts['border_width'] . ' solid #' . $atts['border_color'] . ';' ) . '"';
445
446
			$row_style_attributes = 'text-align:' . ( $atts['direction'] == 'rtl' ? 'right' : 'left' ) . ';';
447
			$row_style_attributes .= 'color:#' . $atts['text_color'] . ';padding:7px 9px;vertical-align:top;';
448
			$row_style_attributes .= 'border-top:' . $atts['border_width'] . ' solid #' . $atts['border_color'] . ';';
449
			$atts['row_style'] = ' style="' . $row_style_attributes . '"';
450
451
			if ( $atts['default_email'] ) {
452
				$atts['bg_color'] = $atts['bg_color_alt'] = ' style="[frm-alt-color]"';
453
			} else {
454
				$atts['bg_color'] = ' style="background-color:#' . $atts['bg_color'] . ';"';
455
				$atts['bg_color_alt'] = ' style="background-color:#' . $atts['alt_bg_color'] . ';"';
456
			}
457
		}
458
	}
459
460
	public static function single_plain_text_row( $atts, &$content ) {
461
		$row = array();
462
		if ( 'rtl' == $atts['direction'] ) {
463
			$row[] = $atts['value']['val'] . ' :' . $atts['value']['label'] . "\r\n";
464
		} else {
465
			$row[] = $atts['value']['label'] . ': ' . $atts['value']['val'] . "\r\n";
466
		}
467
		$row = apply_filters( 'frm_entry_plain_text_row', $row, $atts );
468
		$content = array_merge( $content, $row );
469
	}
470
471
	public static function single_html_row( $atts, &$content ) {
472
		$row = array();
473
		if ( $atts['default_email'] && is_numeric( $atts['id'] ) ) {
474
			self::default_email_row( $atts, $row );
475
		} else {
476
			self::row_content( $atts, $row );
477
		}
478
		$row = apply_filters( 'frm_entry_html_row', $row, $atts );
479
		$content = array_merge( $content, $row );
480
	}
481
482
	public static function html_field_row( $atts, &$content ) {
483
		$content[] = '<tr ' . self::table_row_style( $atts ) . '>';
484
		$content[] = '<td colspan="2" ' . $atts['row_style'] . '>' . $atts['value']['val'] . '</td>';
485
		$content[] = '</tr>' . "\r\n";
486
	}
487
488
	private static function default_email_row( $atts, &$content ) {
489
		$content[] = '[if ' . $atts['id'] . ']';
490
		self::row_content( $atts, $content );
491
		$content[] = '[/if ' . $atts['id'] . ']' . "\r\n";
492
	}
493
494
	private static function row_content( $atts, &$content ) {
495
		$content[] = '<tr' . self::table_row_style( $atts ) . '>';
496
497
		$atts['value']['val'] = str_replace( "\r\n", '<br/>', $atts['value']['val'] );
498
499
		if ( 'rtl' == $atts['direction'] ) {
500
			$first = $atts['value']['val'];
501
			$second = $atts['value']['label'];
502
		} else {
503
			$first = $atts['value']['label'];
504
			$second = $atts['value']['val'];
505
		}
506
507
		$content[] = '<td ' . $atts['row_style'] . '>' . $first . '</td>';
508
		$content[] = '<td ' . $atts['row_style'] . '>' . $second . '</td>';
509
510
		$content[] = '</tr>' . "\r\n";
511
	}
512
513
	private static function table_row_style( $atts ) {
514
		return ( $atts['odd'] ? $atts['bg_color'] : $atts['bg_color_alt'] );
515
	}
516
}
517