Completed
Push — master ( 7f4454...d5b0f5 )
by Stephanie
29:59
created

FrmXMLHelper::get_form_fields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
class FrmXMLHelper {
7
8
	public static function get_xml_values( $opt, $padding ) {
9
		if ( is_array( $opt ) ) {
10
			foreach ( $opt as $ok => $ov ) {
11
				echo "\n" . esc_html( $padding );
12
				$tag = ( is_numeric( $ok ) ? 'key:' : '' ) . $ok;
13
				echo '<' . esc_html( $tag ) . '>';
14
				self::get_xml_values( $ov, $padding . '    ' );
15
				if ( is_array( $ov ) ) {
16
					echo "\n" . esc_html( $padding );
17
				}
18
				echo '</' . esc_html( $tag ) . '>';
19
			}
20
		} else {
21
			echo self::cdata( $opt ); // WPCS: XSS ok.
22
		}
23
	}
24
25
	public static function import_xml( $file ) {
26
		if ( ! defined( 'WP_IMPORTING' ) ) {
27
			define( 'WP_IMPORTING', true );
28
        }
29
30
		if ( ! class_exists( 'DOMDocument' ) ) {
31
            return new WP_Error( 'SimpleXML_parse_error', __( 'Your server does not have XML enabled', 'formidable' ), libxml_get_errors() );
32
        }
33
34
		$dom = new DOMDocument();
35
		$success = $dom->loadXML( file_get_contents( $file ) );
0 ignored issues
show
introduced by
file_get_contents is highly discouraged, please use wpcom_vip_file_get_contents() instead.
Loading history...
36
		if ( ! $success ) {
37
			return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this XML file', 'formidable' ), libxml_get_errors() );
38
		}
39
40
		if ( ! function_exists( 'simplexml_import_dom' ) ) {
41
			return new WP_Error( 'SimpleXML_parse_error', __( 'Your server is missing the simplexml_import_dom function', 'formidable' ), libxml_get_errors() );
42
		}
43
44
		$xml = simplexml_import_dom( $dom );
45
		unset( $dom );
46
47
		// halt if loading produces an error
48
		if ( ! $xml ) {
49
			return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this XML file', 'formidable' ), libxml_get_errors() );
50
		}
51
52
		return self::import_xml_now( $xml );
53
	}
54
55
	/**
56
	 * Add terms, forms (form and field ids), posts (post ids), and entries to db, in that order
57
	 *
58
	 * @since 3.06
59
	 * @return array The number of items imported
60
	 */
61
	public static function import_xml_now( $xml ) {
62
		$imported = self::pre_import_data();
63
64
		foreach ( array( 'term', 'form', 'view' ) as $item_type ) {
65
            // grab cats, tags, and terms, or forms or posts
66
			if ( isset( $xml->{$item_type} ) ) {
67
				$function_name = 'import_xml_' . $item_type . 's';
68
				$imported = self::$function_name( $xml->{$item_type}, $imported );
69
				unset( $function_name, $xml->{$item_type} );
70
            }
71
        }
72
73
		return apply_filters( 'frm_importing_xml', $imported, $xml );
74
	}
75
76
	/**
77
	 * @since 3.06
78
	 * @return array
79
	 */
80
	private static function pre_import_data() {
81
		$defaults = array(
82
			'forms'   => 0,
83
			'fields'  => 0,
84
			'terms'   => 0,
85
			'posts'   => 0,
86
			'views'   => 0,
87
			'actions' => 0,
88
			'styles'  => 0,
89
		);
90
91
		return array(
92
			'imported' => $defaults,
93
			'updated'  => $defaults,
94
			'forms'    => array(),
95
			'terms'    => array(),
96
		);
97
	}
98
99
	public static function import_xml_terms( $terms, $imported ) {
100
        foreach ( $terms as $t ) {
101
			if ( term_exists( (string) $t->term_slug, (string) $t->term_taxonomy ) ) {
102
			    continue;
103
			}
104
105
			$parent = self::get_term_parent_id( $t );
106
107
			$term = wp_insert_term(
108
				(string) $t->term_name,
109
				(string) $t->term_taxonomy,
110
				array(
111
					'slug'          => (string) $t->term_slug,
112
					'description'   => (string) $t->term_description,
113
					'parent'        => empty( $parent ) ? 0 : $parent,
114
				)
115
			);
116
117
			if ( $term && is_array( $term ) ) {
118
                $imported['imported']['terms']++;
119
				$imported['terms'][ (int) $t->term_id ] = $term['term_id'];
120
            }
121
122
			unset( $term, $t );
123
		}
124
125
		return $imported;
126
    }
127
128
	/**
129
	 * @since 2.0.8
130
	 */
131
	private static function get_term_parent_id( $t ) {
132
		$parent = (string) $t->term_parent;
133
		if ( ! empty( $parent ) ) {
134
			$parent = term_exists( (string) $t->term_parent, (string) $t->term_taxonomy );
135
			if ( $parent ) {
136
				$parent = $parent['term_id'];
137
			} else {
138
				$parent = 0;
139
			}
140
		}
141
		return $parent;
142
	}
143
144
	public static function import_xml_forms( $forms, $imported ) {
145
		$child_forms = array();
146
147
		// Import child forms first
148
		self::put_child_forms_first( $forms );
149
150
		foreach ( $forms as $item ) {
151
            $form = self::fill_form( $item );
152
153
			self::update_custom_style_setting_on_import( $form );
154
155
	        $this_form = self::maybe_get_form( $form );
156
157
			$old_id = false;
158
			$form_fields = false;
159
			if ( ! empty( $this_form ) ) {
160
				$form_id = $this_form->id;
161
				$old_id = $this_form->id;
162
				self::update_form( $this_form, $form, $imported );
163
164
				$form_fields = self::get_form_fields( $form_id );
165
			} else {
166
				$form_id = FrmForm::create( $form );
167
		        if ( $form_id ) {
168
		            $imported['imported']['forms']++;
169
		            // Keep track of whether this specific form was updated or not
170
					$imported['form_status'][ $form_id ] = 'imported';
171
					self::track_imported_child_forms( (int) $form_id, $form['parent_form_id'], $child_forms );
172
		        }
173
			}
174
175
			self::import_xml_fields( $item->field, $form_id, $this_form, $form_fields, $imported );
176
177
			self::delete_removed_fields( $form_fields );
178
179
		    // Update field ids/keys to new ones
180
			do_action( 'frm_after_duplicate_form', $form_id, $form, array( 'old_id' => $old_id ) );
181
182
			$imported['forms'][ (int) $item->id ] = $form_id;
183
184
            // Send pre 2.0 form options through function that creates actions
185
            self::migrate_form_settings_to_actions( $form['options'], $form_id, $imported, true );
186
187
			do_action( 'frm_after_import_form', $form_id, $form );
188
189
			unset( $form, $item );
190
		}
191
192
		self::maybe_update_child_form_parent_id( $imported['forms'], $child_forms );
193
194
		return $imported;
195
    }
196
197
	private static function fill_form( $item ) {
198
		$form = array(
199
			'id'            => (int) $item->id,
200
			'form_key'      => (string) $item->form_key,
201
			'name'          => (string) $item->name,
202
			'description'   => (string) $item->description,
203
			'options'       => (string) $item->options,
204
			'logged_in'     => (int) $item->logged_in,
205
			'is_template'   => (int) $item->is_template,
206
			'editable'      => (int) $item->editable,
207
			'status'        => (string) $item->status,
208
			'parent_form_id' => isset( $item->parent_form_id ) ? (int) $item->parent_form_id : 0,
209
			'created_at'    => date( 'Y-m-d H:i:s', strtotime( (string) $item->created_at ) ),
210
		);
211
		$form['options'] = FrmAppHelper::maybe_json_decode( $form['options'] );
212
		return $form;
213
	}
214
215
	private static function maybe_get_form( $form ) {
216
		// if template, allow to edit if form keys match, otherwise, creation date must also match
217
		$edit_query = array(
218
			'form_key'    => $form['form_key'],
219
			'is_template' => $form['is_template'],
220
		);
221
		if ( ! $form['is_template'] ) {
222
			$edit_query['created_at'] = $form['created_at'];
223
		}
224
225
		$edit_query = apply_filters( 'frm_match_xml_form', $edit_query, $form );
226
227
		return FrmForm::getAll( $edit_query, '', 1 );
228
	}
229
230
	private static function update_form( $this_form, $form, &$imported ) {
231
		$form_id = $this_form->id;
232
		FrmForm::update( $form_id, $form );
233
		$imported['updated']['forms']++;
234
		// Keep track of whether this specific form was updated or not
235
		$imported['form_status'][ $form_id ] = 'updated';
236
	}
237
238
	private static function get_form_fields( $form_id ) {
239
		$form_fields = FrmField::get_all_for_form( $form_id, '', 'exclude', 'exclude' );
240
		$old_fields = array();
241
		foreach ( $form_fields as $f ) {
242
			$old_fields[ $f->id ] = $f;
243
			$old_fields[ $f->field_key ] = $f->id;
244
			unset( $f );
245
		}
246
		$form_fields = $old_fields;
247
		return $form_fields;
248
	}
249
250
	/**
251
	 * Delete any fields attached to this form that were not included in the template
252
	 */
253
	private static function delete_removed_fields( $form_fields ) {
254
		if ( ! empty( $form_fields ) ) {
255
			foreach ( $form_fields as $field ) {
256
				if ( is_object( $field ) ) {
257
					FrmField::destroy( $field->id );
258
				}
259
				unset( $field );
260
			}
261
		}
262
	}
263
264
	/**
265
	* Put child forms first so they will be imported before parents
266
	*
267
	* @since 2.0.16
268
	* @param array $forms
269
	*/
270
	private static function put_child_forms_first( &$forms ) {
271
		$child_forms = array();
272
		$regular_forms = array();
273
274
		foreach ( $forms as $form ) {
275
			$parent_form_id = isset( $form->parent_form_id ) ? (int) $form->parent_form_id : 0;
276
277
			if ( $parent_form_id ) {
278
				$child_forms[] = $form;
279
			} else {
280
				$regular_forms[] = $form;
281
			}
282
		}
283
284
		$forms = array_merge( $child_forms, $regular_forms );
285
	}
286
287
	/**
288
	* Keep track of all imported child forms
289
	*
290
	* @since 2.0.16
291
	* @param int $form_id
292
	* @param int $parent_form_id
293
	* @param array $child_forms
294
	*/
295
	private static function track_imported_child_forms( $form_id, $parent_form_id, &$child_forms ) {
296
		if ( $parent_form_id ) {
297
			$child_forms[ $form_id ] = $parent_form_id;
298
		}
299
	}
300
301
	/**
302
	* Update the parent_form_id on imported child forms
303
	* Child forms are imported first so their parent_form_id will need to be updated after the parent is imported
304
	*
305
	* @since 2.0.6
306
	* @param array $imported_forms
307
	* @param array $child_forms
308
	*/
309
	private static function maybe_update_child_form_parent_id( $imported_forms, $child_forms ) {
310
		foreach ( $child_forms as $child_form_id => $old_parent_form_id ) {
311
312
			if ( isset( $imported_forms[ $old_parent_form_id ] ) && $imported_forms[ $old_parent_form_id ] != $old_parent_form_id ) {
313
				// Update all children with this old parent_form_id
314
				$new_parent_form_id = (int) $imported_forms[ $old_parent_form_id ];
315
316
				FrmForm::update( $child_form_id, array( 'parent_form_id' => $new_parent_form_id ) );
317
			}
318
		}
319
	}
320
321
	/**
322
	* Import all fields for a form
323
	 *
324
	* @since 2.0.13
325
	*
326
	* TODO: Cut down on params
327
	*/
328
	private static function import_xml_fields( $xml_fields, $form_id, $this_form, &$form_fields, &$imported ) {
329
		$in_section = 0;
330
331
		foreach ( $xml_fields as $field ) {
332
			$f = self::fill_field( $field, $form_id );
333
334
			$has_default = array( 'text', 'email', 'url', 'textarea', 'number', 'phone', 'date', 'hidden', 'password', 'tag' );
335
			if ( is_array( $f['default_value'] ) && in_array( $f['type'], $has_default, true ) ) {
336
				if ( count( $f['default_value'] ) === 1 ) {
337
					$f['default_value'] = '[' . reset( $f['default_value'] ) . ']';
338
				} else {
339
					$f['default_value'] = reset( $f['default_value'] );
340
				}
341
			}
342
343
			self::maybe_update_in_section_variable( $in_section, $f );
344
			self::maybe_update_form_select( $f, $imported );
345
			self::maybe_update_get_values_form_setting( $imported, $f );
346
347
			if ( ! empty( $this_form ) ) {
348
				// check for field to edit by field id
349
				if ( isset( $form_fields[ $f['id'] ] ) ) {
350
					FrmField::update( $f['id'], $f );
351
					$imported['updated']['fields']++;
352
353
					unset( $form_fields[ $f['id'] ] );
354
355
					//unset old field key
356
					if ( isset( $form_fields[ $f['field_key'] ] ) ) {
357
						unset( $form_fields[ $f['field_key'] ] );
358
					}
359
				} else if ( isset( $form_fields[ $f['field_key'] ] ) ) {
360
					// check for field to edit by field key
361
					unset( $f['id'] );
362
363
					FrmField::update( $form_fields[ $f['field_key'] ], $f );
364
					$imported['updated']['fields']++;
365
366
					unset( $form_fields[ $form_fields[ $f['field_key'] ] ] ); //unset old field id
367
					unset( $form_fields[ $f['field_key'] ] ); //unset old field key
368
				} else {
369
					// if no matching field id or key in this form, create the field
370
					self::create_imported_field( $f, $imported );
371
				}
372
			} else {
373
374
				self::create_imported_field( $f, $imported );
375
			}
376
		}
377
	}
378
379
	private static function fill_field( $field, $form_id ) {
380
		return array(
381
			'id'            => (int) $field->id,
382
			'field_key'     => (string) $field->field_key,
383
			'name'          => (string) $field->name,
384
			'description'   => (string) $field->description,
385
			'type'          => (string) $field->type,
386
			'default_value' => FrmAppHelper::maybe_json_decode( (string) $field->default_value ),
387
			'field_order'   => (int) $field->field_order,
388
			'form_id'       => (int) $form_id,
389
			'required'      => (int) $field->required,
390
			'options'       => FrmAppHelper::maybe_json_decode( (string) $field->options ),
391
			'field_options' => FrmAppHelper::maybe_json_decode( (string) $field->field_options ),
392
		);
393
	}
394
395
	/**
396
	 * Update the current in_section value
397
	 *
398
	 * @since 2.0.25
399
	 * @param int $in_section
400
	 * @param array $f
401
	 */
402
	private static function maybe_update_in_section_variable( &$in_section, &$f ) {
403
		// If we're at the end of a section, switch $in_section is 0
404
		if ( in_array( $f['type'], array( 'end_divider', 'break', 'form' ) ) ) {
405
			$in_section = 0;
406
		}
407
408
		// Update the current field's in_section value
409
		if ( ! isset( $f['field_options']['in_section'] ) ) {
410
			$f['field_options']['in_section'] = $in_section;
411
		}
412
413
		// If we're starting a new section, switch $in_section to ID of divider
414
		if ( $f['type'] == 'divider' ) {
415
			$in_section = $f['id'];
416
		}
417
	}
418
419
	/**
420
	* Switch the form_select on a repeating field or embedded form if it needs to be switched
421
	*
422
	* @since 2.0.16
423
	* @param array $f
424
	* @param array $imported
425
	*/
426
	private static function maybe_update_form_select( &$f, $imported ) {
427
		if ( ! isset( $imported['forms'] ) ) {
428
			return;
429
		}
430
431
		if ( $f['type'] == 'form' || ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) ) {
432 View Code Duplication
			if ( FrmField::is_option_true( $f['field_options'], 'form_select' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
433
				$form_select = (int) $f['field_options']['form_select'];
434
				if ( isset( $imported['forms'][ $form_select ] ) ) {
435
					$f['field_options']['form_select'] = $imported['forms'][ $form_select ];
436
				}
437
			}
438
		}
439
	}
440
441
	/**
442
	 * Update the get_values_form setting if the form was imported
443
	 *
444
	 * @since 2.01.0
445
	 * @param array $imported
446
	 * @param array $f
447
	 */
448
	private static function maybe_update_get_values_form_setting( $imported, &$f ) {
449
		if ( ! isset( $imported['forms'] ) ) {
450
			return;
451
		}
452
453 View Code Duplication
		if ( FrmField::is_option_true_in_array( $f['field_options'], 'get_values_form' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
454
			$old_form = $f['field_options']['get_values_form'];
455
			if ( isset( $imported['forms'][ $old_form ] ) ) {
456
				$f['field_options']['get_values_form'] = $imported['forms'][ $old_form ];
457
			}
458
		}
459
	}
460
461
	/**
462
	 * Create an imported field
463
	 *
464
	 * @since 2.0.25
465
	 * @param array $f
466
	 * @param array $imported
467
	 */
468
	private static function create_imported_field( $f, &$imported ) {
469
		$defaults           = self::default_field_options( $f['type'] );
470
		$f['field_options'] = array_merge( $defaults, $f['field_options'] );
471
472
		$new_id = FrmField::create( $f );
473
		if ( $new_id != false ) {
474
			$imported['imported']['fields']++;
475
			do_action( 'frm_after_field_is_imported', $f, $new_id );
476
		}
477
	}
478
479
	/**
480
	* Updates the custom style setting on import
481
	* Convert the post slug to an ID
482
	*
483
	* @since 2.0.19
484
	* @param array $form
485
	*/
486
	private static function update_custom_style_setting_on_import( &$form ) {
487
		if ( ! isset( $form['options']['custom_style'] ) ) {
488
			return;
489
		}
490
491
		if ( is_numeric( $form['options']['custom_style'] ) ) {
492
			// Set to default
493
			$form['options']['custom_style'] = 1;
494
		} else {
495
			// Replace the style name with the style ID on import
496
			global $wpdb;
497
			$table = $wpdb->prefix . 'posts';
498
			$where = array(
499
				'post_name' => $form['options']['custom_style'],
500
				'post_type' => 'frm_styles',
501
			);
502
			$select = 'ID';
503
			$style_id = FrmDb::get_var( $table, $where, $select );
504
505
			if ( $style_id ) {
506
				$form['options']['custom_style'] = $style_id;
507
			} else {
508
				// save the old style to maybe update after styles import
509
				$form['options']['old_style'] = $form['options']['custom_style'];
510
511
				// Set to default
512
				$form['options']['custom_style'] = 1;
513
			}
514
		}
515
	}
516
517
	/**
518
	 * After styles are imported, check for any forms that were linked
519
	 * and link them back up.
520
	 *
521
	 * @since 2.2.7
522
	 */
523
	private static function update_custom_style_setting_after_import( $form_id ) {
524
		$form = FrmForm::getOne( $form_id );
525
526
		if ( $form && isset( $form->options['old_style'] ) ) {
527
			$form = (array) $form;
528
			$saved_style = $form['options']['custom_style'];
529
			$form['options']['custom_style'] = $form['options']['old_style'];
530
			self::update_custom_style_setting_on_import( $form );
531
			$has_changed = ( $form['options']['custom_style'] != $saved_style && $form['options']['custom_style'] != $form['options']['old_style'] );
532
			if ( $has_changed ) {
533
				FrmForm::update( $form['id'], $form );
534
			}
535
		}
536
	}
537
538
	public static function import_xml_views( $views, $imported ) {
539
        $imported['posts'] = array();
540
        $form_action_type = FrmFormActionsController::$action_post_type;
541
542
        $post_types = array(
543
            'frm_display' => 'views',
544
            $form_action_type => 'actions',
545
            'frm_styles'    => 'styles',
546
        );
547
548
        foreach ( $views as $item ) {
549
			$post = array(
550
				'post_title'    => (string) $item->title,
551
				'post_name'     => (string) $item->post_name,
552
				'post_type'     => (string) $item->post_type,
553
				'post_password' => (string) $item->post_password,
554
				'guid'          => (string) $item->guid,
555
				'post_status'   => (string) $item->status,
556
				'post_author'   => FrmAppHelper::get_user_id_param( (string) $item->post_author ),
557
				'post_id'       => (int) $item->post_id,
558
				'post_parent'   => (int) $item->post_parent,
559
				'menu_order'    => (int) $item->menu_order,
560
				'post_content'  => FrmFieldsHelper::switch_field_ids( (string) $item->content ),
561
				'post_excerpt'  => FrmFieldsHelper::switch_field_ids( (string) $item->excerpt ),
562
				'is_sticky'     => (string) $item->is_sticky,
563
				'comment_status' => (string) $item->comment_status,
564
				'post_date'     => (string) $item->post_date,
565
				'post_date_gmt' => (string) $item->post_date_gmt,
566
				'ping_status'   => (string) $item->ping_status,
567
                'postmeta'      => array(),
568
                'tax_input'     => array(),
569
			);
570
571
            $old_id = $post['post_id'];
572
			self::populate_post( $post, $item, $imported );
573
574
			unset( $item );
575
576
			$post_id = false;
577
            if ( $post['post_type'] == $form_action_type ) {
578
                $action_control = FrmFormActionsController::get_form_actions( $post['post_excerpt'] );
579
				if ( $action_control && is_object( $action_control ) ) {
580
					$post_id = $action_control->maybe_create_action( $post, $imported['form_status'] );
581
				}
582
				unset( $action_control );
583
            } else if ( $post['post_type'] == 'frm_styles' ) {
584
                // Properly encode post content before inserting the post
585
                $post['post_content'] = FrmAppHelper::maybe_json_decode( $post['post_content'] );
586
				$custom_css = isset( $post['post_content']['custom_css'] ) ? $post['post_content']['custom_css'] : '';
587
                $post['post_content'] = FrmAppHelper::prepare_and_encode( $post['post_content'] );
588
589
                // Create/update post now
590
                $post_id = wp_insert_post( $post );
591
				self::maybe_update_custom_css( $custom_css );
592
            } else {
593
                // Create/update post now
594
                $post_id = wp_insert_post( $post );
595
            }
596
597
			if ( ! is_numeric( $post_id ) ) {
598
                continue;
599
            }
600
601
			self::update_postmeta( $post, $post_id );
602
603
            $this_type = 'posts';
604
			if ( isset( $post_types[ $post['post_type'] ] ) ) {
605
				$this_type = $post_types[ $post['post_type'] ];
606
            }
607
608
			if ( isset( $post['ID'] ) && $post_id == $post['ID'] ) {
609
                $imported['updated'][ $this_type ]++;
610
            } else {
611
                $imported['imported'][ $this_type ]++;
612
            }
613
614
			$imported['posts'][ (int) $old_id ] = $post_id;
615
616
			do_action( 'frm_after_import_view', $post_id, $post );
617
618
			unset( $post );
619
		}
620
621
		self::maybe_update_stylesheet( $imported );
622
623
		return $imported;
624
    }
625
626
    private static function populate_post( &$post, $item, $imported ) {
627
		if ( isset( $item->attachment_url ) ) {
628
			$post['attachment_url'] = (string) $item->attachment_url;
629
		}
630
631
		if ( $post['post_type'] == FrmFormActionsController::$action_post_type && isset( $imported['forms'][ (int) $post['menu_order'] ] ) ) {
632
		    // update to new form id
633
		    $post['menu_order'] = $imported['forms'][ (int) $post['menu_order'] ];
634
		}
635
636
		// Don't allow default styles to take over a site's default style
637
		if ( 'frm_styles' == $post['post_type'] ) {
638
			$post['menu_order'] = 0;
639
		}
640
641
		foreach ( $item->postmeta as $meta ) {
642
			self::populate_postmeta( $post, $meta, $imported );
643
			unset( $meta );
644
		}
645
646
		self::populate_taxonomies( $post, $item );
647
648
		self::maybe_editing_post( $post );
649
    }
650
651
    private static function populate_postmeta( &$post, $meta, $imported ) {
652
        global $frm_duplicate_ids;
653
654
	    $m = array(
655
			'key'   => (string) $meta->meta_key,
656
			'value' => (string) $meta->meta_value,
657
		);
658
659
		//switch old form and field ids to new ones
660
		if ( $m['key'] == 'frm_form_id' && isset( $imported['forms'][ (int) $m['value'] ] ) ) {
661
		    $m['value'] = $imported['forms'][ (int) $m['value'] ];
662
		} else {
663
		    $m['value'] = FrmAppHelper::maybe_json_decode( $m['value'] );
664
665
			if ( ! empty( $frm_duplicate_ids ) ) {
666
667
		        if ( $m['key'] == 'frm_dyncontent' ) {
668
					$m['value'] = FrmFieldsHelper::switch_field_ids( $m['value'] );
669
    		    } else if ( $m['key'] == 'frm_options' ) {
670
671
					foreach ( array( 'date_field_id', 'edate_field_id' ) as $setting_name ) {
672
						if ( isset( $m['value'][ $setting_name ] ) && is_numeric( $m['value'][ $setting_name ] ) && isset( $frm_duplicate_ids[ $m['value'][ $setting_name ] ] ) ) {
673
							$m['value'][ $setting_name ] = $frm_duplicate_ids[ $m['value'][ $setting_name ] ];
674
    		            }
675
    		        }
676
677
                    $check_dup_array = array();
678
    		        if ( isset( $m['value']['order_by'] ) && ! empty( $m['value']['order_by'] ) ) {
679
    		            if ( is_numeric( $m['value']['order_by'] ) && isset( $frm_duplicate_ids[ $m['value']['order_by'] ] ) ) {
680
    		                $m['value']['order_by'] = $frm_duplicate_ids[ $m['value']['order_by'] ];
681
    		            } else if ( is_array( $m['value']['order_by'] ) ) {
682
                            $check_dup_array[] = 'order_by';
683
    		            }
684
    		        }
685
686
    		        if ( isset( $m['value']['where'] ) && ! empty( $m['value']['where'] ) ) {
687
    		            $check_dup_array[] = 'where';
688
    		        }
689
690
                    foreach ( $check_dup_array as $check_k ) {
691
						foreach ( (array) $m['value'][ $check_k ] as $mk => $mv ) {
692
							if ( isset( $frm_duplicate_ids[ $mv ] ) ) {
693
								$m['value'][ $check_k ][ $mk ] = $frm_duplicate_ids[ $mv ];
694
		                    }
695
							unset( $mk, $mv );
696
		                }
697
                    }
698
    		    }
699
		    }
700
		}
701
702
		if ( ! is_array( $m['value'] ) ) {
703
			$m['value'] = FrmAppHelper::maybe_json_decode( $m['value'] );
704
		}
705
706
		$post['postmeta'][ (string) $meta->meta_key ] = $m['value'];
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
707
    }
708
709
    /**
710
     * Add terms to post
711
	 *
712
     * @param array $post by reference
713
     * @param object $item The XML object data
714
     */
715
    private static function populate_taxonomies( &$post, $item ) {
716
		foreach ( $item->category as $c ) {
717
			$att = $c->attributes();
718
			if ( ! isset( $att['nicename'] ) ) {
719
                continue;
720
            }
721
722
		    $taxonomy = (string) $att['domain'];
723
			if ( is_taxonomy_hierarchical( $taxonomy ) ) {
724
		        $name = (string) $att['nicename'];
725
				$h_term = get_term_by( 'slug', $name, $taxonomy );
726
		        if ( $h_term ) {
727
		            $name = $h_term->term_id;
728
		        }
729
				unset( $h_term );
730
		    } else {
731
		        $name = (string) $c;
732
		    }
733
734
			if ( ! isset( $post['tax_input'][ $taxonomy ] ) ) {
735
				$post['tax_input'][ $taxonomy ] = array();
736
			}
737
738
			$post['tax_input'][ $taxonomy ][] = $name;
739
			unset( $name );
740
		}
741
    }
742
743
    /**
744
     * Edit post if the key and created time match
745
     */
746
    private static function maybe_editing_post( &$post ) {
747
		$match_by = array(
748
		    'post_type'     => $post['post_type'],
749
		    'name'          => $post['post_name'],
750
		    'post_status'   => $post['post_status'],
751
		    'posts_per_page' => 1,
752
		);
753
754
		if ( in_array( $post['post_status'], array( 'trash', 'draft' ) ) ) {
755
		    $match_by['include'] = $post['post_id'];
756
			unset( $match_by['name'] );
757
		}
758
759
		$editing = get_posts( $match_by );
760
761
		if ( ! empty( $editing ) && current( $editing )->post_date == $post['post_date'] ) {
762
			// set the id of the post to edit
763
			$post['ID'] = current( $editing )->ID;
764
		}
765
    }
766
767
    private static function update_postmeta( &$post, $post_id ) {
768
        foreach ( $post['postmeta'] as $k => $v ) {
769
            if ( '_edit_last' == $k ) {
770
				$v = FrmAppHelper::get_user_id_param( $v );
771
            } else if ( '_thumbnail_id' == $k && FrmAppHelper::pro_is_installed() ) {
772
                //change the attachment ID
773
				$field_obj = FrmFieldFactory::get_field_type( 'file' );
774
				$v = $field_obj->get_file_id( $v );
775
            }
776
777
			update_post_meta( $post_id, $k, $v );
778
779
			unset( $k, $v );
780
        }
781
    }
782
783
	/**
784
	 * If a template includes custom css, let's include it.
785
	 * The custom css is included on the default style.
786
	 *
787
	 * @since 2.03
788
	 */
789
	private static function maybe_update_custom_css( $custom_css ) {
790
		if ( empty( $custom_css ) ) {
791
			return;
792
		}
793
794
		$frm_style = new FrmStyle();
795
		$default_style = $frm_style->get_default_style();
796
		$default_style->post_content['custom_css'] .= "\r\n\r\n" . $custom_css;
797
		$frm_style->save( $default_style );
798
	}
799
800
	private static function maybe_update_stylesheet( $imported ) {
801
		$new_styles = isset( $imported['imported']['styles'] ) && ! empty( $imported['imported']['styles'] );
802
		$updated_styles = isset( $imported['updated']['styles'] ) && ! empty( $imported['updated']['styles'] );
803
		if ( $new_styles || $updated_styles ) {
804
			if ( is_admin() && function_exists( 'get_filesystem_method' ) ) {
805
				$frm_style = new FrmStyle();
806
				$frm_style->update( 'default' );
807
			}
808
			foreach ( $imported['forms'] as $form_id ) {
809
				self::update_custom_style_setting_after_import( $form_id );
810
			}
811
		}
812
	}
813
814
    /**
815
     * @param string $message
816
     */
817
	public static function parse_message( $result, &$message, &$errors ) {
818
		if ( is_wp_error( $result ) ) {
819
            $errors[] = $result->get_error_message();
820
        } else if ( ! $result ) {
821
            return;
822
        }
823
824
		if ( ! is_array( $result ) ) {
825
            $message = is_string( $result ) ? $result : htmlentities( print_r( $result, 1 ) );
0 ignored issues
show
introduced by
The use of function print_r() is discouraged
Loading history...
826
            return;
827
        }
828
829
        $t_strings = array(
830
            'imported'  => __( 'Imported', 'formidable' ),
831
            'updated'   => __( 'Updated', 'formidable' ),
832
        );
833
834
        $message = '<ul>';
835
        foreach ( $result as $type => $results ) {
836
			if ( ! isset( $t_strings[ $type ] ) ) {
837
                // only print imported and updated
838
                continue;
839
            }
840
841
			$s_message = array();
842
			foreach ( $results as $k => $m ) {
843
				self::item_count_message( $m, $k, $s_message );
844
				unset( $k, $m );
845
			}
846
847
			if ( ! empty( $s_message ) ) {
848
				$message .= '<li><strong>' . $t_strings[ $type ] . ':</strong> ';
849
				$message .= implode( ', ', $s_message );
850
				$message .= '</li>';
851
			}
852
        }
853
854
        if ( $message == '<ul>' ) {
855
            $message = '';
856
            $errors[] = __( 'Nothing was imported or updated', 'formidable' );
857
        } else {
858
            $message .= '</ul>';
859
        }
860
    }
861
862
	public static function item_count_message( $m, $type, &$s_message ) {
863
        if ( ! $m ) {
864
            return;
865
        }
866
867
        $strings = array(
868
            'forms'     => sprintf( _n( '%1$s Form', '%1$s Forms', $m, 'formidable' ), $m ),
869
            'fields'    => sprintf( _n( '%1$s Field', '%1$s Fields', $m, 'formidable' ), $m ),
870
            'items'     => sprintf( _n( '%1$s Entry', '%1$s Entries', $m, 'formidable' ), $m ),
871
            'views'     => sprintf( _n( '%1$s View', '%1$s Views', $m, 'formidable' ), $m ),
872
            'posts'     => sprintf( _n( '%1$s Post', '%1$s Posts', $m, 'formidable' ), $m ),
873
            'styles'     => sprintf( _n( '%1$s Style', '%1$s Styles', $m, 'formidable' ), $m ),
874
            'terms'     => sprintf( _n( '%1$s Term', '%1$s Terms', $m, 'formidable' ), $m ),
875
            'actions'   => sprintf( _n( '%1$s Form Action', '%1$s Form Actions', $m, 'formidable' ), $m ),
876
        );
877
878
		$s_message[] = isset( $strings[ $type ] ) ? $strings[ $type ] : ' ' . $m . ' ' . ucfirst( $type );
879
    }
880
881
	/**
882
	 * Prepare the form options for export
883
	 *
884
	 * @since 2.0.19
885
	 * @param string $options
886
	 * @return string
887
	 */
888
	public static function prepare_form_options_for_export( $options ) {
889
		$options = maybe_unserialize( $options );
890
		// Change custom_style to the post_name instead of ID (1 may be a string)
891
		$not_default = isset( $options['custom_style'] ) && 1 != $options['custom_style'];
892
		if ( $not_default ) {
893
			global $wpdb;
894
			$table = $wpdb->prefix . 'posts';
895
			$where = array( 'ID' => $options['custom_style'] );
896
			$select = 'post_name';
897
898
			$style_name = FrmDb::get_var( $table, $where, $select );
899
900
			if ( $style_name ) {
901
				$options['custom_style'] = $style_name;
902
			} else {
903
				$options['custom_style'] = 1;
904
			}
905
		}
906
		self::remove_default_form_options( $options );
907
		$options = serialize( $options );
908
		return self::cdata( $options );
909
	}
910
911
	/**
912
	 * If the saved value is the same as the default, remove it from the export
913
	 * This keeps file size down and prevents overriding global settings after import
914
	 *
915
	 * @since 3.06
916
	 */
917
	private static function remove_default_form_options( &$options ) {
918
		$defaults = FrmFormsHelper::get_default_opts();
919
		if ( is_callable( 'FrmProFormsHelper::get_default_opts' ) ) {
920
			$defaults += FrmProFormsHelper::get_default_opts();
921
		}
922
 		self::remove_defaults( $defaults, $options );
923
	}
924
925
	/**
926
	 * Remove extra settings from field to keep file size down
927
	 *
928
	 * @since 3.06
929
	 */
930
	public static function prepare_field_for_export( &$field ) {
931
		self::remove_default_field_options( $field );
932
	}
933
934
	/**
935
	 * Remove defaults from field options too
936
	 *
937
	 * @since 3.06
938
	 */
939
	private static function remove_default_field_options( &$field ) {
940
		$defaults = self::default_field_options( $field->type );
941
		if ( empty( $defaults['blank'] ) ) {
942
			$global_settings = new FrmSettings();
943
			$global_defaults = $global_settings->default_options();
944
			$defaults['blank'] = $global_defaults['blank_msg'];
945
		}
946
947
		$options = maybe_unserialize( $field->field_options );
948
 		self::remove_defaults( $defaults, $options );
949
		self::remove_default_html( 'custom_html', $defaults, $options );
950
951
		// Get variations on the defaults.
952
		if ( isset( $options['invalid'] ) ) {
953
			$defaults = array(
954
				'invalid' => sprintf( __( '%s is invalid', 'formidable' ), $field->name ),
955
			);
956
			self::remove_defaults( $defaults, $options );
957
		}
958
959
		$field->field_options = serialize( $options );
960
	}
961
962
	/**
963
	 * @since 3.06.03
964
	 */
965
	private static function default_field_options( $type ) {
966
		$defaults = FrmFieldsHelper::get_default_field_options( $type );
967
		if ( empty( $defaults['custom_html'] ) ) {
968
			$defaults['custom_html'] = FrmFieldsHelper::get_default_html( $type );
969
		}
970
		return $defaults;
971
	}
972
973
 	/**
0 ignored issues
show
Coding Style introduced by
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
974
	 * Compare the default array to the saved values and
975
	 * remove if they are the same
976
	 *
977
	 * @since 3.06
978
	 */
979
	private static function remove_defaults( $defaults, &$saved ) {
980
		$array_defaults = array_filter( $defaults, 'is_array' );
981
		foreach ( $array_defaults as $d => $default ) {
982
			// compare array defaults
983
			if ( $default == $saved[ $d ] ) {
984
				unset( $saved[ $d ] );
985
			}
986
			unset( $defaults[ $d ] );
987
		}
988
 		$saved = array_diff_assoc( (array) $saved, $defaults );
989
	}
990
991
 	/**
0 ignored issues
show
Coding Style introduced by
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
992
	 * The line endings may prevent html from being equal when it should
993
	 *
994
	 * @since 3.06
995
	 */
996
	private static function remove_default_html( $html_name, $defaults, &$options ) {
997
		if ( ! isset( $options[ $html_name ] ) || ! isset( $defaults[ $html_name ] ) ) {
998
			return;
999
		}
1000
1001
		$old_html = str_replace( "\r\n", "\n", $options[ $html_name ] );
1002
		$default_html = $defaults[ $html_name ];
1003
		if ( $old_html == $default_html ) {
1004
			unset( $options[ $html_name ] );
1005
			return;
1006
		}
1007
1008
		// Account for some of the older field default HTML.
1009
		$default_html = str_replace( ' id="frm_desc_field_[key]"', '', $default_html );
1010
		if ( $old_html == $default_html ) {
1011
			unset( $options[ $html_name ] );
1012
		}
1013
	}
1014
1015
	public static function cdata( $str ) {
1016
		$str = maybe_unserialize( $str );
1017
		if ( is_array( $str ) ) {
1018
			$str = json_encode( $str );
1019
		} else if ( seems_utf8( $str ) == false ) {
1020
			$str = utf8_encode( $str );
1021
		}
1022
1023
		if ( is_numeric( $str ) ) {
1024
            return $str;
1025
        }
1026
1027
		self::remove_invalid_characters_from_xml( $str );
1028
1029
		// $str = ent2ncr(esc_html( $str));
1030
		$str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>';
1031
1032
		return $str;
1033
	}
1034
1035
	/**
1036
	 * Remove <US> character (unit separator) from exported strings
1037
	 *
1038
	 * @since 2.0.22
1039
	 * @param string $str
1040
	 */
1041
	private static function remove_invalid_characters_from_xml( &$str ) {
1042
		// Remove <US> character
1043
		$str = str_replace( '\x1F', '', $str );
1044
	}
1045
1046
    public static function migrate_form_settings_to_actions( $form_options, $form_id, &$imported = array(), $switch = false ) {
1047
        // Get post type
1048
        $post_type = FrmFormActionsController::$action_post_type;
1049
1050
        // Set up imported index, if not set up yet
1051
        if ( ! isset( $imported['imported']['actions'] ) ) {
1052
            $imported['imported']['actions'] = 0;
1053
        }
1054
1055
        // Migrate post settings to action
1056
        self::migrate_post_settings_to_action( $form_options, $form_id, $post_type, $imported, $switch );
1057
1058
        // Migrate email settings to action
1059
        self::migrate_email_settings_to_action( $form_options, $form_id, $post_type, $imported, $switch );
1060
    }
1061
1062
    /**
1063
    * Migrate post settings to form action
1064
    *
1065
    * @param string $post_type
1066
    */
1067
    private static function migrate_post_settings_to_action( $form_options, $form_id, $post_type, &$imported, $switch ) {
1068
		if ( ! isset( $form_options['create_post'] ) || ! $form_options['create_post'] ) {
1069
            return;
1070
        }
1071
1072
        $new_action = array(
1073
            'post_type'     => $post_type,
1074
            'post_excerpt'  => 'wppost',
1075
			'post_title'    => __( 'Create Posts', 'formidable' ),
1076
            'menu_order'    => $form_id,
1077
            'post_status'   => 'publish',
1078
            'post_content'  => array(),
1079
			'post_name'     => $form_id . '_wppost_1',
1080
        );
1081
1082
		$post_settings = array( 'post_type', 'post_category', 'post_content', 'post_excerpt', 'post_title', 'post_name', 'post_date', 'post_status', 'post_custom_fields', 'post_password' );
1083
1084
        foreach ( $post_settings as $post_setting ) {
1085
			if ( isset( $form_options[ $post_setting ] ) ) {
1086
				$new_action['post_content'][ $post_setting ] = $form_options[ $post_setting ];
1087
            }
1088
			unset( $post_setting );
1089
        }
1090
1091
		$new_action['event'] = array( 'create', 'update' );
1092
1093
        if ( $switch ) {
1094
			// Fields with string or int saved
1095
			$basic_fields = array( 'post_title', 'post_content', 'post_excerpt', 'post_password', 'post_date', 'post_status' );
1096
1097
			// Fields with arrays saved
1098
			$array_fields = array( 'post_category', 'post_custom_fields' );
1099
1100
			$new_action['post_content'] = self::switch_action_field_ids( $new_action['post_content'], $basic_fields, $array_fields );
1101
        }
1102
		$new_action['post_content'] = json_encode( $new_action['post_content'] );
1103
1104
		$exists = get_posts(
1105
			array(
1106
				'name'          => $new_action['post_name'],
1107
				'post_type'     => $new_action['post_type'],
1108
				'post_status'   => $new_action['post_status'],
1109
				'numberposts'   => 1,
1110
			)
1111
		);
1112
1113
        if ( ! $exists ) {
1114
			// this isn't an email, but we need to use a class that will always be included
1115
			FrmDb::save_json_post( $new_action );
1116
            $imported['imported']['actions']++;
1117
        }
1118
    }
1119
1120
	/**
1121
	 * Switch old field IDs for new field IDs in emails and post
1122
	 *
1123
	 * @since 2.0
1124
	 * @param array $post_content - check for old field IDs
1125
	 * @param array $basic_fields - fields with string or int saved
1126
	 * @param array $array_fields - fields with arrays saved
1127
	 *
1128
	 * @return string $post_content - new field IDs
1129
	 */
1130
	private static function switch_action_field_ids( $post_content, $basic_fields, $array_fields = array() ) {
1131
        global $frm_duplicate_ids;
1132
1133
        // If there aren't IDs that were switched, end now
1134
        if ( ! $frm_duplicate_ids ) {
1135
            return;
1136
        }
1137
1138
        // Get old IDs
1139
        $old = array_keys( $frm_duplicate_ids );
1140
1141
        // Get new IDs
1142
        $new = array_values( $frm_duplicate_ids );
1143
1144
        // Do a str_replace with each item to set the new IDs
1145
        foreach ( $post_content as $key => $setting ) {
1146
            if ( ! is_array( $setting ) && in_array( $key, $basic_fields ) ) {
1147
                // Replace old IDs with new IDs
1148
				$post_content[ $key ] = str_replace( $old, $new, $setting );
1149
            } else if ( is_array( $setting ) && in_array( $key, $array_fields ) ) {
1150
                foreach ( $setting as $k => $val ) {
1151
                    // Replace old IDs with new IDs
1152
					$post_content[ $key ][ $k ] = str_replace( $old, $new, $val );
1153
                }
1154
            }
1155
            unset( $key, $setting );
1156
        }
1157
        return $post_content;
1158
    }
1159
1160
    private static function migrate_email_settings_to_action( $form_options, $form_id, $post_type, &$imported, $switch ) {
1161
        // No old notifications or autoresponders to carry over
1162
		if ( ! isset( $form_options['auto_responder'] ) && ! isset( $form_options['notification'] ) && ! isset( $form_options['email_to'] ) ) {
1163
            return;
1164
        }
1165
1166
        // Initialize notifications array
1167
        $notifications = array();
1168
1169
        // Migrate regular notifications
1170
        self::migrate_notifications_to_action( $form_options, $form_id, $notifications );
1171
1172
        // Migrate autoresponders
1173
        self::migrate_autoresponder_to_action( $form_options, $form_id, $notifications );
1174
1175
        if ( empty( $notifications ) ) {
1176
            return;
1177
        }
1178
1179
        foreach ( $notifications as $new_notification ) {
1180
            $new_notification['post_type']      = $post_type;
1181
            $new_notification['post_excerpt']   = 'email';
1182
			$new_notification['post_title']     = __( 'Email Notification', 'formidable' );
1183
            $new_notification['menu_order']     = $form_id;
1184
            $new_notification['post_status']    = 'publish';
1185
1186
            // Switch field IDs and keys, if needed
1187
            if ( $switch ) {
1188
1189
				// Switch field IDs in email conditional logic
1190
				self::switch_email_contition_field_ids( $new_notification['post_content'] );
1191
1192
				// Switch all other field IDs in email
1193
                $new_notification['post_content'] = FrmFieldsHelper::switch_field_ids( $new_notification['post_content'] );
1194
            }
1195
            $new_notification['post_content']   = FrmAppHelper::prepare_and_encode( $new_notification['post_content'] );
1196
1197
			$exists = get_posts(
1198
				array(
1199
					'name'          => $new_notification['post_name'],
1200
					'post_type'     => $new_notification['post_type'],
1201
					'post_status'   => $new_notification['post_status'],
1202
					'numberposts'   => 1,
1203
				)
1204
			);
1205
1206
			if ( empty( $exists ) ) {
1207
				FrmDb::save_json_post( $new_notification );
1208
                $imported['imported']['actions']++;
1209
            }
1210
			unset( $new_notification );
1211
        }
1212
1213
		self::remove_deprecated_notification_settings( $form_id, $form_options );
1214
    }
1215
1216
	/**
1217
	 * Remove deprecated notification settings after migration
1218
	 *
1219
	 * @since 2.05
1220
	 *
1221
	 * @param int|string $form_id
1222
	 * @param array $form_options
1223
	 */
1224
	private static function remove_deprecated_notification_settings( $form_id, $form_options ) {
1225
		$delete_settings = array( 'notification', 'autoresponder', 'email_to' );
1226
		foreach ( $delete_settings as $index ) {
1227
			if ( isset( $form_options[ $index ] ) ) {
1228
				unset( $form_options[ $index ] );
1229
			}
1230
		}
1231
		FrmForm::update( $form_id, array( 'options' => $form_options ) );
1232
	}
1233
1234
    private static function migrate_notifications_to_action( $form_options, $form_id, &$notifications ) {
1235
        if ( ! isset( $form_options['notification'] ) && isset( $form_options['email_to'] ) && ! empty( $form_options['email_to'] ) ) {
1236
            // add old settings into notification array
1237
			$form_options['notification'] = array( 0 => $form_options );
1238
        } else if ( isset( $form_options['notification']['email_to'] ) ) {
1239
            // make sure it's in the correct format
1240
			$form_options['notification'] = array( 0 => $form_options['notification'] );
1241
        }
1242
1243
		if ( isset( $form_options['notification'] ) && is_array( $form_options['notification'] ) ) {
1244
            foreach ( $form_options['notification'] as $email_key => $notification ) {
1245
1246
				$atts = array(
1247
					'email_to'  => '',
1248
					'reply_to'  => '',
1249
					'reply_to_name' => '',
1250
					'event'     => '',
1251
					'form_id'   => $form_id,
1252
					'email_key' => $email_key,
1253
				);
1254
1255
                // Format the email data
1256
                self::format_email_data( $atts, $notification );
1257
1258
				if ( isset( $notification['twilio'] ) && $notification['twilio'] ) {
1259
					do_action( 'frm_create_twilio_action', $atts, $notification );
1260
				}
1261
1262
                // Setup the new notification
1263
                $new_notification = array();
1264
                self::setup_new_notification( $new_notification, $notification, $atts );
1265
1266
                $notifications[] = $new_notification;
1267
            }
1268
        }
1269
    }
1270
1271
    private static function format_email_data( &$atts, $notification ) {
1272
        // Format email_to
1273
        self::format_email_to_data( $atts, $notification );
1274
1275
        // Format the reply to email and name
1276
		$reply_fields = array(
1277
			'reply_to'      => '',
1278
			'reply_to_name' => '',
1279
		);
1280
        foreach ( $reply_fields as $f => $val ) {
1281
			if ( isset( $notification[ $f ] ) ) {
1282
				$atts[ $f ] = $notification[ $f ];
1283
				if ( 'custom' == $notification[ $f ] ) {
1284
					$atts[ $f ] = $notification[ 'cust_' . $f ];
1285
				} else if ( is_numeric( $atts[ $f ] ) && ! empty( $atts[ $f ] ) ) {
1286
					$atts[ $f ] = '[' . $atts[ $f ] . ']';
1287
                }
1288
            }
1289
            unset( $f, $val );
1290
        }
1291
1292
        // Format event
1293
		$atts['event'] = array( 'create' );
1294
        if ( isset( $notification['update_email'] ) && 1 == $notification['update_email'] ) {
1295
            $atts['event'][] = 'update';
1296
		} elseif ( isset( $notification['update_email'] ) && 2 == $notification['update_email'] ) {
1297
			$atts['event'] = array( 'update' );
1298
        }
1299
    }
1300
1301
    private static function format_email_to_data( &$atts, $notification ) {
1302
        if ( isset( $notification['email_to'] ) ) {
1303
			$atts['email_to'] = preg_split( '/ (,|;) /', $notification['email_to'] );
1304
        } else {
1305
            $atts['email_to'] = array();
1306
        }
1307
1308
        if ( isset( $notification['also_email_to'] ) ) {
1309
            $email_fields = (array) $notification['also_email_to'];
1310
            $atts['email_to'] = array_merge( $email_fields, $atts['email_to'] );
1311
            unset( $email_fields );
1312
        }
1313
1314
        foreach ( $atts['email_to'] as $key => $email_field ) {
1315
1316
            if ( is_numeric( $email_field ) ) {
1317
				$atts['email_to'][ $key ] = '[' . $email_field . ']';
1318
            }
1319
1320
			if ( strpos( $email_field, '|' ) ) {
1321
                $email_opt = explode( '|', $email_field );
1322
                if ( isset( $email_opt[0] ) ) {
1323
					$atts['email_to'][ $key ] = '[' . $email_opt[0] . ' show=' . $email_opt[1] . ']';
1324
                }
1325
                unset( $email_opt );
1326
            }
1327
        }
1328
		$atts['email_to'] = implode( ', ', $atts['email_to'] );
1329
    }
1330
1331
    private static function setup_new_notification( &$new_notification, $notification, $atts ) {
1332
        // Set up new notification
1333
        $new_notification = array(
1334
            'post_content'  => array(
1335
                'email_to'      => $atts['email_to'],
1336
                'event'         => $atts['event'],
1337
            ),
1338
			'post_name'         => $atts['form_id'] . '_email_' . $atts['email_key'],
1339
        );
1340
1341
        // Add more fields to the new notification
1342
        $add_fields = array( 'email_message', 'email_subject', 'plain_text', 'inc_user_info', 'conditions' );
1343
        foreach ( $add_fields as $add_field ) {
1344
			if ( isset( $notification[ $add_field ] ) ) {
1345
				$new_notification['post_content'][ $add_field ] = $notification[ $add_field ];
1346
            } else if ( in_array( $add_field, array( 'plain_text', 'inc_user_info' ) ) ) {
1347
				$new_notification['post_content'][ $add_field ] = 0;
1348
            } else {
1349
				$new_notification['post_content'][ $add_field ] = '';
1350
            }
1351
            unset( $add_field );
1352
        }
1353
1354
		// Set reply to
1355
		$new_notification['post_content']['reply_to'] = $atts['reply_to'];
1356
1357
        // Set from
1358
		if ( ! empty( $atts['reply_to'] ) || ! empty( $atts['reply_to_name'] ) ) {
1359
			$new_notification['post_content']['from'] = ( empty( $atts['reply_to_name'] ) ? '[sitename]' : $atts['reply_to_name'] ) . ' <' . ( empty( $atts['reply_to'] ) ? '[admin_email]' : $atts['reply_to'] ) . '>';
1360
        }
1361
    }
1362
1363
	/**
1364
	* Switch field IDs in pre-2.0 email conditional logic
1365
	*
1366
	* @param $post_content array, pass by reference
1367
	*/
1368
	private static function switch_email_contition_field_ids( &$post_content ) {
1369
		// Switch field IDs in conditional logic
1370
		if ( isset( $post_content['conditions'] ) && is_array( $post_content['conditions'] ) ) {
1371
			foreach ( $post_content['conditions'] as $email_key => $val ) {
1372
				if ( is_numeric( $email_key ) ) {
1373
					$post_content['conditions'][ $email_key ] = self::switch_action_field_ids( $val, array( 'hide_field' ) );
1374
				}
1375
				unset( $email_key, $val );
1376
			}
1377
		}
1378
	}
1379
1380
    private static function migrate_autoresponder_to_action( $form_options, $form_id, &$notifications ) {
1381
		if ( isset( $form_options['auto_responder'] ) && $form_options['auto_responder'] && isset( $form_options['ar_email_message'] ) && $form_options['ar_email_message'] ) {
1382
			// migrate autoresponder
1383
1384
			$email_field = isset( $form_options['ar_email_to'] ) ? $form_options['ar_email_to'] : 0;
1385
			if ( strpos( $email_field, '|' ) ) {
1386
				// data from entries field
1387
				$email_field = explode( '|', $email_field );
1388
				if ( isset( $email_field[1] ) ) {
1389
					$email_field = $email_field[1];
1390
				}
1391
			}
1392
			if ( is_numeric( $email_field ) && ! empty( $email_field ) ) {
1393
				$email_field = '[' . $email_field . ']';
1394
			}
1395
1396
            $notification = $form_options;
1397
            $new_notification2 = array(
1398
				'post_content'  => array(
1399
					'email_message' => $notification['ar_email_message'],
1400
					'email_subject' => isset( $notification['ar_email_subject'] ) ? $notification['ar_email_subject'] : '',
1401
					'email_to'      => $email_field,
1402
					'plain_text'    => isset( $notification['ar_plain_text'] ) ? $notification['ar_plain_text'] : 0,
1403
					'inc_user_info' => 0,
1404
				),
1405
				'post_name'     => $form_id . '_email_' . count( $notifications ),
1406
            );
1407
1408
			$reply_to = isset( $notification['ar_reply_to'] ) ? $notification['ar_reply_to'] : '';
1409
			$reply_to_name = isset( $notification['ar_reply_to_name'] ) ? $notification['ar_reply_to_name'] : '';
1410
1411
			if ( ! empty( $reply_to ) ) {
1412
				$new_notification2['post_content']['reply_to'] = $reply_to;
1413
			}
1414
1415
			if ( ! empty( $reply_to ) || ! empty( $reply_to_name ) ) {
1416
				$new_notification2['post_content']['from'] = ( empty( $reply_to_name ) ? '[sitename]' : $reply_to_name ) . ' <' . ( empty( $reply_to ) ? '[admin_email]' : $reply_to ) . '>';
1417
			}
1418
1419
            $notifications[] = $new_notification2;
1420
            unset( $new_notification2 );
1421
        }
1422
    }
1423
}
1424
1425