Passed
Push — master ( ec16eb...0357f3 )
by Stephanie
03:05
created

FrmXMLHelper::delete_removed_fields()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 4
nop 1
dl 0
loc 7
rs 9.2
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" . $padding;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$padding'
Loading history...
12
				$tag = ( is_numeric( $ok ) ? 'key:' : '' ) . $ok;
13
				echo '<' . $tag . '>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$tag'
Loading history...
14
				self::get_xml_values( $ov, $padding . '    ' );
15
				if ( is_array( $ov ) ) {
16
					echo "\n" . $padding;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$padding'
Loading history...
17
				}
18
				echo '</' . $tag . '>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$tag'
Loading history...
19
			}
20
		} else {
21
			echo self::cdata( $opt );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not 'self'
Loading history...
22
		}
23
	}
24
25
	public static function import_xml( $file ) {
26
		$defaults = array(
27
			'forms'   => 0,
28
			'fields'  => 0,
29
			'terms'   => 0,
30
			'posts'   => 0,
31
			'views'   => 0,
32
			'actions' => 0,
33
			'styles'  => 0,
34
		);
35
36
        $imported = array(
37
            'imported' => $defaults,
38
			'updated'  => $defaults,
39
			'forms'    => array(),
40
			'terms'    => array(),
41
        );
42
43
        unset($defaults);
44
45
		if ( ! defined( 'WP_IMPORTING' ) ) {
46
            define('WP_IMPORTING', true);
47
        }
48
49
		if ( ! class_exists( 'DOMDocument' ) ) {
50
            return new WP_Error( 'SimpleXML_parse_error', __( 'Your server does not have XML enabled', 'formidable' ), libxml_get_errors() );
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
            return new WP_Error( 'SimpleXML_parse_error', /** @scrutinizer ignore-call */ __( 'Your server does not have XML enabled', 'formidable' ), libxml_get_errors() );
Loading history...
Bug introduced by
The type WP_Error was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
51
        }
52
53
        $dom = new DOMDocument;
54
		$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...
55
		if ( ! $success ) {
56
			return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this XML file', 'formidable' ), libxml_get_errors() );
57
		}
58
59
		if ( ! function_exists('simplexml_import_dom') ) {
60
			return new WP_Error( 'SimpleXML_parse_error', __( 'Your server is missing the simplexml_import_dom function', 'formidable' ), libxml_get_errors() );
61
		}
62
63
		$xml = simplexml_import_dom( $dom );
64
		unset( $dom );
65
66
		// halt if loading produces an error
67
		if ( ! $xml ) {
0 ignored issues
show
introduced by
The condition ! $xml can never be false.
Loading history...
68
			return new WP_Error( 'SimpleXML_parse_error', __( 'There was an error when reading this XML file', 'formidable' ), libxml_get_errors() );
69
		}
70
71
        // add terms, forms (form and field ids), posts (post ids), and entries to db, in that order
72
		foreach ( array( 'term', 'form', 'view' ) as $item_type ) {
73
            // grab cats, tags, and terms, or forms or posts
74
            if ( isset($xml->{$item_type} ) ) {
75
				$function_name = 'import_xml_' . $item_type . 's';
76
				$imported = self::$function_name( $xml->{$item_type}, $imported );
77
				unset( $function_name, $xml->{$item_type} );
78
            }
79
        }
80
81
	    $return = apply_filters('frm_importing_xml', $imported, $xml );
0 ignored issues
show
Bug introduced by
The function apply_filters was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
	    $return = /** @scrutinizer ignore-call */ apply_filters('frm_importing_xml', $imported, $xml );
Loading history...
82
83
	    return $return;
84
    }
85
86
	public static function import_xml_terms( $terms, $imported ) {
87
        foreach ( $terms as $t ) {
88
			if ( term_exists( (string) $t->term_slug, (string) $t->term_taxonomy ) ) {
0 ignored issues
show
Bug introduced by
The function term_exists was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
			if ( /** @scrutinizer ignore-call */ term_exists( (string) $t->term_slug, (string) $t->term_taxonomy ) ) {
Loading history...
89
			    continue;
90
			}
91
92
			$parent = self::get_term_parent_id( $t );
93
94
			$term = wp_insert_term( (string) $t->term_name, (string) $t->term_taxonomy, array(
0 ignored issues
show
Bug introduced by
The function wp_insert_term was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

94
			$term = /** @scrutinizer ignore-call */ wp_insert_term( (string) $t->term_name, (string) $t->term_taxonomy, array(
Loading history...
95
                'slug'          => (string) $t->term_slug,
96
                'description'   => (string) $t->term_description,
97
				'parent'        => empty( $parent ) ? 0 : $parent,
98
            ));
99
100
			if ( $term && is_array( $term ) ) {
101
                $imported['imported']['terms']++;
102
				$imported['terms'][ (int) $t->term_id ] = $term['term_id'];
103
            }
104
105
			unset( $term, $t );
106
		}
107
108
		return $imported;
109
    }
110
111
	/**
112
	 * @since 2.0.8
113
	 */
114
	private static function get_term_parent_id( $t ) {
115
		$parent = (string) $t->term_parent;
116
		if ( ! empty( $parent ) ) {
117
			$parent = term_exists( (string) $t->term_parent, (string) $t->term_taxonomy );
0 ignored issues
show
Bug introduced by
The function term_exists was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

117
			$parent = /** @scrutinizer ignore-call */ term_exists( (string) $t->term_parent, (string) $t->term_taxonomy );
Loading history...
118
			if ( $parent ) {
119
				$parent = $parent['term_id'];
120
			} else {
121
				$parent = 0;
122
			}
123
		}
124
		return $parent;
125
	}
126
127
	public static function import_xml_forms( $forms, $imported ) {
128
		$child_forms = array();
129
130
		// Import child forms first
131
		self::put_child_forms_first( $forms );
132
133
		foreach ( $forms as $item ) {
134
            $form = self::fill_form( $item );
135
136
			self::update_custom_style_setting_on_import( $form );
137
138
	        $this_form = self::maybe_get_form( $form );
139
140
			$old_id = false;
141
			$form_fields = false;
142
			if ( ! empty( $this_form ) ) {
143
				$form_id = $this_form->id;
144
				$old_id = $this_form->id;
145
				self::update_form( $this_form, $form, $imported );
146
147
				$form_fields = self::get_form_fields( $form_id );
148
			} else {
149
				$form_id = FrmForm::create( $form );
150
		        if ( $form_id ) {
151
		            $imported['imported']['forms']++;
152
		            // Keep track of whether this specific form was updated or not
153
					$imported['form_status'][ $form_id ] = 'imported';
154
					self::track_imported_child_forms( (int) $form_id, $form['parent_form_id'], $child_forms );
155
		        }
156
			}
157
158
			self::import_xml_fields( $item->field, $form_id, $this_form, $form_fields, $imported );
159
160
			self::delete_removed_fields( $form_fields );
161
162
		    // Update field ids/keys to new ones
163
			do_action( 'frm_after_duplicate_form', $form_id, $form, array( 'old_id' => $old_id ) );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

163
			/** @scrutinizer ignore-call */ 
164
   do_action( 'frm_after_duplicate_form', $form_id, $form, array( 'old_id' => $old_id ) );
Loading history...
164
165
			$imported['forms'][ (int) $item->id ] = $form_id;
166
167
            // Send pre 2.0 form options through function that creates actions
168
            self::migrate_form_settings_to_actions( $form['options'], $form_id, $imported, true );
169
170
			do_action( 'frm_after_import_form', $form_id, $form );
171
172
		    unset($form, $item);
173
		}
174
175
		self::maybe_update_child_form_parent_id( $imported['forms'], $child_forms );
176
177
		return $imported;
178
    }
179
180
	private static function fill_form( $item ) {
181
		$form = array(
182
			'id'            => (int) $item->id,
183
			'form_key'      => (string) $item->form_key,
184
			'name'          => (string) $item->name,
185
			'description'   => (string) $item->description,
186
			'options'       => (string) $item->options,
187
			'logged_in'     => (int) $item->logged_in,
188
			'is_template'   => (int) $item->is_template,
189
			'default_template' => (int) $item->default_template,
190
			'editable'      => (int) $item->editable,
191
			'status'        => (string) $item->status,
192
			'parent_form_id' => isset( $item->parent_form_id ) ? (int) $item->parent_form_id : 0,
193
			'created_at'    => date( 'Y-m-d H:i:s', strtotime( (string) $item->created_at ) ),
194
		);
195
		$form['options'] = FrmAppHelper::maybe_json_decode( $form['options'] );
196
		return $form;
197
	}
198
199
	private static function maybe_get_form( $form ) {
200
		// if template, allow to edit if form keys match, otherwise, creation date must also match
201
		$edit_query = array(
202
			'form_key'    => $form['form_key'],
203
			'is_template' => $form['is_template'],
204
		);
205
		if ( ! $form['is_template'] ) {
206
			$edit_query['created_at'] = $form['created_at'];
207
		}
208
209
		$edit_query = apply_filters( 'frm_match_xml_form', $edit_query, $form );
0 ignored issues
show
Bug introduced by
The function apply_filters was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

209
		$edit_query = /** @scrutinizer ignore-call */ apply_filters( 'frm_match_xml_form', $edit_query, $form );
Loading history...
210
211
		return FrmForm::getAll( $edit_query, '', 1 );
212
	}
213
214
	private static function update_form( $this_form, $form, &$imported ) {
215
		$form_id = $this_form->id;
216
		FrmForm::update( $form_id, $form );
217
		$imported['updated']['forms']++;
218
		// Keep track of whether this specific form was updated or not
219
		$imported['form_status'][ $form_id ] = 'updated';
220
	}
221
222
	private static function get_form_fields( $form_id ) {
223
		$form_fields = FrmField::get_all_for_form( $form_id, '', 'exclude', 'exclude' );
224
		$old_fields = array();
225
		foreach ( $form_fields as $f ) {
226
			$old_fields[ $f->id ] = $f;
227
			$old_fields[ $f->field_key ] = $f->id;
228
			unset($f);
229
		}
230
		$form_fields = $old_fields;
231
		return $form_fields;
232
	}
233
234
	/**
235
	 * Delete any fields attached to this form that were not included in the template
236
	 */
237
	private static function delete_removed_fields( $form_fields ) {
238
		if ( ! empty( $form_fields ) ) {
239
			foreach ( $form_fields as $field ) {
240
				if ( is_object( $field ) ) {
241
					FrmField::destroy( $field->id );
242
				}
243
				unset( $field );
244
			}
245
		}
246
	}
247
248
	/**
249
	* Put child forms first so they will be imported before parents
250
	*
251
	* @since 2.0.16
252
	* @param array $forms
253
	*/
254
	private static function put_child_forms_first( &$forms ) {
255
		$child_forms = array();
256
		$regular_forms = array();
257
258
		foreach ( $forms as $form ) {
259
			$parent_form_id = isset( $form->parent_form_id) ? (int) $form->parent_form_id : 0;
260
261
			if ( $parent_form_id ) {
262
				$child_forms[] = $form;
263
			} else {
264
				$regular_forms[] = $form;
265
			}
266
		}
267
268
		$forms = array_merge( $child_forms, $regular_forms );
269
	}
270
271
	/**
272
	* Keep track of all imported child forms
273
	*
274
	* @since 2.0.16
275
	* @param int $form_id
276
	* @param int $parent_form_id
277
	* @param array $child_forms
278
	*/
279
	private static function track_imported_child_forms( $form_id, $parent_form_id, &$child_forms ) {
280
		if ( $parent_form_id ) {
281
			$child_forms[ $form_id ] = $parent_form_id;
282
		}
283
	}
284
285
	/**
286
	* Update the parent_form_id on imported child forms
287
	* Child forms are imported first so their parent_form_id will need to be updated after the parent is imported
288
	*
289
	* @since 2.0.6
290
	* @param array $imported_forms
291
	* @param array $child_forms
292
	*/
293
	private static function maybe_update_child_form_parent_id( $imported_forms, $child_forms ) {
294
		foreach ( $child_forms as $child_form_id => $old_parent_form_id ) {
295
296
			if ( isset( $imported_forms[ $old_parent_form_id ] ) && $imported_forms[ $old_parent_form_id ] != $old_parent_form_id ) {
297
				// Update all children with this old parent_form_id
298
				$new_parent_form_id = (int) $imported_forms[ $old_parent_form_id ];
299
300
				FrmForm::update( $child_form_id, array( 'parent_form_id' => $new_parent_form_id ) );
301
			}
302
		}
303
	}
304
305
	/**
306
	* Import all fields for a form
307
	* @since 2.0.13
308
	*
309
	* TODO: Cut down on params
310
	*/
311
	private static function import_xml_fields( $xml_fields, $form_id, $this_form, &$form_fields, &$imported ) {
312
		$in_section = 0;
313
314
		foreach ( $xml_fields as $field ) {
315
			$f = self::fill_field( $field, $form_id );
316
317
			$has_default = array( 'text', 'email', 'url', 'textarea', 'number', 'phone', 'date', 'hidden', 'password', 'tag' );
318
			if ( is_array( $f['default_value'] ) && in_array( $f['type'], $has_default, true ) ) {
319
				if ( count( $f['default_value'] ) === 1 ) {
320
					$f['default_value'] = '[' . reset( $f['default_value'] ) . ']';
321
				} else {
322
					$f['default_value'] = reset( $f['default_value'] );
323
				}
324
			}
325
326
			self::maybe_update_in_section_variable( $in_section, $f );
327
			self::maybe_update_form_select( $f, $imported );
328
			self::maybe_update_get_values_form_setting( $imported, $f );
329
330
			if ( ! empty($this_form) ) {
331
				// check for field to edit by field id
332
				if ( isset( $form_fields[ $f['id'] ] ) ) {
333
					FrmField::update( $f['id'], $f );
334
					$imported['updated']['fields']++;
335
336
					unset( $form_fields[ $f['id'] ] );
337
338
					//unset old field key
339
					if ( isset( $form_fields[ $f['field_key'] ] ) ) {
340
						unset( $form_fields[ $f['field_key'] ] );
341
					}
342
				} else if ( isset( $form_fields[ $f['field_key'] ] ) ) {
343
					// check for field to edit by field key
344
					unset($f['id']);
345
346
					FrmField::update( $form_fields[ $f['field_key'] ], $f );
347
					$imported['updated']['fields']++;
348
349
					unset( $form_fields[ $form_fields[ $f['field_key'] ] ] ); //unset old field id
350
					unset( $form_fields[ $f['field_key'] ] ); //unset old field key
351
				} else {
352
					// if no matching field id or key in this form, create the field
353
					self::create_imported_field( $f, $imported );
354
				}
355
			} else {
356
357
				self::create_imported_field( $f, $imported );
358
			}
359
		}
360
	}
361
362
	private static function fill_field( $field, $form_id ) {
363
		return array(
364
			'id'            => (int) $field->id,
365
			'field_key'     => (string) $field->field_key,
366
			'name'          => (string) $field->name,
367
			'description'   => (string) $field->description,
368
			'type'          => (string) $field->type,
369
			'default_value' => FrmAppHelper::maybe_json_decode( (string) $field->default_value),
370
			'field_order'   => (int) $field->field_order,
371
			'form_id'       => (int) $form_id,
372
			'required'      => (int) $field->required,
373
			'options'       => FrmAppHelper::maybe_json_decode( (string) $field->options),
374
			'field_options' => FrmAppHelper::maybe_json_decode( (string) $field->field_options ),
375
		);
376
	}
377
378
	/**
379
	 * Update the current in_section value
380
	 *
381
	 * @since 2.0.25
382
	 * @param int $in_section
383
	 * @param array $f
384
	 */
385
	private static function maybe_update_in_section_variable( &$in_section, &$f ) {
386
		// If we're at the end of a section, switch $in_section is 0
387
		if ( in_array( $f['type'], array( 'end_divider', 'break', 'form' ) ) ) {
388
			$in_section = 0;
389
		}
390
391
		// Update the current field's in_section value
392
		if ( ! isset( $f['field_options']['in_section'] ) ) {
393
			$f['field_options']['in_section'] = $in_section;
394
		}
395
396
		// If we're starting a new section, switch $in_section to ID of divider
397
		if ( $f['type'] == 'divider' ) {
398
			$in_section = $f['id'];
399
		}
400
	}
401
402
	/**
403
	* Switch the form_select on a repeating field or embedded form if it needs to be switched
404
	*
405
	* @since 2.0.16
406
	* @param array $f
407
	* @param array $imported
408
	*/
409
	private static function maybe_update_form_select( &$f, $imported ) {
410
		if ( ! isset( $imported['forms'] ) ) {
411
			return;
412
		}
413
414
		if ( $f['type'] == 'form' || ( $f['type'] == 'divider' && FrmField::is_option_true( $f['field_options'], 'repeat' ) ) ) {
415
			if ( FrmField::is_option_true( $f['field_options'], 'form_select' ) ) {
416
				$form_select = (int) $f['field_options']['form_select'];
417
				if ( isset( $imported['forms'][ $form_select ] ) ) {
418
					$f['field_options']['form_select'] = $imported['forms'][ $form_select ];
419
				}
420
			}
421
		}
422
	}
423
424
	/**
425
	 * Update the get_values_form setting if the form was imported
426
	 *
427
	 * @since 2.01.0
428
	 * @param array $imported
429
	 * @param array $f
430
	 */
431
	private static function maybe_update_get_values_form_setting( $imported, &$f ) {
432
		if ( ! isset( $imported['forms'] ) ) {
433
			return;
434
		}
435
436
		if ( FrmField::is_option_true_in_array( $f['field_options'], 'get_values_form' ) ) {
437
			$old_form = $f['field_options']['get_values_form'];
438
			if ( isset( $imported['forms'][ $old_form ] ) ) {
439
				$f['field_options']['get_values_form'] = $imported['forms'][ $old_form ];
440
			}
441
		}
442
	}
443
444
	/**
445
	 * Create an imported field
446
	 *
447
	 * @since 2.0.25
448
	 * @param array $f
449
	 * @param array $imported
450
	 */
451
	private static function create_imported_field( $f, &$imported ) {
452
		$new_id = FrmField::create( $f );
453
		if ( $new_id != false ) {
454
			$imported['imported']['fields']++;
455
			do_action( 'frm_after_field_is_imported', $f, $new_id );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

455
			/** @scrutinizer ignore-call */ 
456
   do_action( 'frm_after_field_is_imported', $f, $new_id );
Loading history...
456
		}
457
	}
458
459
	/**
460
	* Updates the custom style setting on import
461
	* Convert the post slug to an ID
462
	*
463
	* @since 2.0.19
464
	* @param array $form
465
	*
466
	*/
467
	private static function update_custom_style_setting_on_import( &$form ) {
468
		if ( ! isset( $form['options']['custom_style'] ) ) {
469
			return;
470
		}
471
472
		if ( is_numeric( $form['options']['custom_style'] ) ) {
473
			// Set to default
474
			$form['options']['custom_style'] = 1;
475
		} else {
476
			// Replace the style name with the style ID on import
477
			global $wpdb;
478
			$table = $wpdb->prefix . 'posts';
479
			$where = array(
480
				'post_name' => $form['options']['custom_style'],
481
				'post_type' => 'frm_styles',
482
			);
483
			$select = 'ID';
484
			$style_id = FrmDb::get_var( $table, $where, $select );
485
486
			if ( $style_id ) {
487
				$form['options']['custom_style'] = $style_id;
488
			} else {
489
				// save the old style to maybe update after styles import
490
				$form['options']['old_style'] = $form['options']['custom_style'];
491
492
				// Set to default
493
				$form['options']['custom_style'] = 1;
494
			}
495
		}
496
	}
497
498
	/**
499
	 * After styles are imported, check for any forms that were linked
500
	 * and link them back up.
501
	 *
502
	 * @since 2.2.7
503
	 */
504
	private static function update_custom_style_setting_after_import( $form_id ) {
505
		$form = FrmForm::getOne( $form_id );
506
507
		if ( $form && isset( $form->options['old_style'] ) ) {
0 ignored issues
show
introduced by
The condition $form && IssetNode can never be true.
Loading history...
508
			$form = (array) $form;
509
			$saved_style = $form['options']['custom_style'];
510
			$form['options']['custom_style'] = $form['options']['old_style'];
511
			self::update_custom_style_setting_on_import( $form );
512
			$has_changed = ( $form['options']['custom_style'] != $saved_style && $form['options']['custom_style'] != $form['options']['old_style'] );
513
			if ( $has_changed ) {
514
				FrmForm::update( $form['id'], $form );
515
			}
516
		}
517
	}
518
519
	public static function import_xml_views( $views, $imported ) {
520
        $imported['posts'] = array();
521
        $form_action_type = FrmFormActionsController::$action_post_type;
522
523
        $post_types = array(
524
            'frm_display' => 'views',
525
            $form_action_type => 'actions',
526
            'frm_styles'    => 'styles',
527
        );
528
529
        foreach ( $views as $item ) {
530
			$post = array(
531
				'post_title'    => (string) $item->title,
532
				'post_name'     => (string) $item->post_name,
533
				'post_type'     => (string) $item->post_type,
534
				'post_password' => (string) $item->post_password,
535
				'guid'          => (string) $item->guid,
536
				'post_status'   => (string) $item->status,
537
				'post_author'   => FrmAppHelper::get_user_id_param( (string) $item->post_author ),
538
				'post_id'       => (int) $item->post_id,
539
				'post_parent'   => (int) $item->post_parent,
540
				'menu_order'    => (int) $item->menu_order,
541
				'post_content'  => FrmFieldsHelper::switch_field_ids( (string) $item->content ),
542
				'post_excerpt'  => FrmFieldsHelper::switch_field_ids( (string) $item->excerpt ),
543
				'is_sticky'     => (string) $item->is_sticky,
544
				'comment_status' => (string) $item->comment_status,
545
				'post_date'     => (string) $item->post_date,
546
				'post_date_gmt' => (string) $item->post_date_gmt,
547
				'ping_status'   => (string) $item->ping_status,
548
                'postmeta'      => array(),
549
                'tax_input'     => array(),
550
			);
551
552
            $old_id = $post['post_id'];
553
            self::populate_post($post, $item, $imported);
554
555
			unset($item);
556
557
			$post_id = false;
558
            if ( $post['post_type'] == $form_action_type ) {
559
                $action_control = FrmFormActionsController::get_form_actions( $post['post_excerpt'] );
560
				if ( $action_control && is_object( $action_control ) ) {
561
					$post_id = $action_control->maybe_create_action( $post, $imported['form_status'] );
562
				}
563
                unset($action_control);
564
            } else if ( $post['post_type'] == 'frm_styles' ) {
565
                // Properly encode post content before inserting the post
566
                $post['post_content'] = FrmAppHelper::maybe_json_decode( $post['post_content'] );
567
				$custom_css = isset( $post['post_content']['custom_css'] ) ? $post['post_content']['custom_css'] : '';
568
                $post['post_content'] = FrmAppHelper::prepare_and_encode( $post['post_content'] );
0 ignored issues
show
Bug introduced by
It seems like $post['post_content'] can also be of type string; however, parameter $post_content of FrmAppHelper::prepare_and_encode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

568
                $post['post_content'] = FrmAppHelper::prepare_and_encode( /** @scrutinizer ignore-type */ $post['post_content'] );
Loading history...
569
570
                // Create/update post now
571
                $post_id = wp_insert_post( $post );
0 ignored issues
show
Bug introduced by
The function wp_insert_post was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

571
                $post_id = /** @scrutinizer ignore-call */ wp_insert_post( $post );
Loading history...
572
				self::maybe_update_custom_css( $custom_css );
573
            } else {
574
                // Create/update post now
575
                $post_id = wp_insert_post( $post );
576
            }
577
578
            if ( ! is_numeric($post_id) ) {
579
                continue;
580
            }
581
582
            self::update_postmeta($post, $post_id);
583
584
            $this_type = 'posts';
585
			if ( isset( $post_types[ $post['post_type'] ] ) ) {
586
				$this_type = $post_types[ $post['post_type'] ];
587
            }
588
589
            if ( isset($post['ID']) && $post_id == $post['ID'] ) {
590
                $imported['updated'][ $this_type ]++;
591
            } else {
592
                $imported['imported'][ $this_type ]++;
593
            }
594
595
			$imported['posts'][ (int) $old_id ] = $post_id;
596
597
			do_action( 'frm_after_import_view', $post_id, $post );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

597
			/** @scrutinizer ignore-call */ 
598
   do_action( 'frm_after_import_view', $post_id, $post );
Loading history...
598
599
			unset( $post );
600
		}
601
602
		self::maybe_update_stylesheet( $imported );
603
604
		return $imported;
605
    }
606
607
    private static function populate_post( &$post, $item, $imported ) {
608
		if ( isset($item->attachment_url) ) {
609
			$post['attachment_url'] = (string) $item->attachment_url;
610
		}
611
612
		if ( $post['post_type'] == FrmFormActionsController::$action_post_type && isset( $imported['forms'][ (int) $post['menu_order'] ] ) ) {
613
		    // update to new form id
614
		    $post['menu_order'] = $imported['forms'][ (int) $post['menu_order'] ];
615
		}
616
617
		// Don't allow default styles to take over a site's default style
618
		if ( 'frm_styles' == $post['post_type'] ) {
619
			$post['menu_order'] = 0;
620
		}
621
622
		foreach ( $item->postmeta as $meta ) {
623
		    self::populate_postmeta($post, $meta, $imported);
624
			unset($meta);
625
		}
626
627
        self::populate_taxonomies($post, $item);
628
629
        self::maybe_editing_post($post);
630
    }
631
632
    private static function populate_postmeta( &$post, $meta, $imported ) {
633
        global $frm_duplicate_ids;
634
635
	    $m = array(
636
			'key'   => (string) $meta->meta_key,
637
			'value' => (string) $meta->meta_value,
638
		);
639
640
		//switch old form and field ids to new ones
641
		if ( $m['key'] == 'frm_form_id' && isset($imported['forms'][ (int) $m['value'] ]) ) {
642
		    $m['value'] = $imported['forms'][ (int) $m['value'] ];
643
		} else {
644
		    $m['value'] = FrmAppHelper::maybe_json_decode($m['value']);
645
646
		    if ( ! empty($frm_duplicate_ids) ) {
647
648
		        if ( $m['key'] == 'frm_dyncontent' ) {
649
		            $m['value'] = FrmFieldsHelper::switch_field_ids($m['value']);
650
    		    } else if ( $m['key'] == 'frm_options' ) {
651
652
					foreach ( array( 'date_field_id', 'edate_field_id' ) as $setting_name ) {
653
						if ( isset( $m['value'][ $setting_name ] ) && is_numeric( $m['value'][ $setting_name ] ) && isset( $frm_duplicate_ids[ $m['value'][ $setting_name ] ] ) ) {
654
							$m['value'][ $setting_name ] = $frm_duplicate_ids[ $m['value'][ $setting_name ] ];
655
    		            }
656
    		        }
657
658
                    $check_dup_array = array();
659
    		        if ( isset( $m['value']['order_by'] ) && ! empty( $m['value']['order_by'] ) ) {
660
    		            if ( is_numeric( $m['value']['order_by'] ) && isset( $frm_duplicate_ids[ $m['value']['order_by'] ] ) ) {
661
    		                $m['value']['order_by'] = $frm_duplicate_ids[ $m['value']['order_by'] ];
662
    		            } else if ( is_array( $m['value']['order_by'] ) ) {
663
                            $check_dup_array[] = 'order_by';
664
    		            }
665
    		        }
666
667
    		        if ( isset( $m['value']['where'] ) && ! empty( $m['value']['where'] ) ) {
668
    		            $check_dup_array[] = 'where';
669
    		        }
670
671
                    foreach ( $check_dup_array as $check_k ) {
672
						foreach ( (array) $m['value'][ $check_k ] as $mk => $mv ) {
673
							if ( isset( $frm_duplicate_ids[ $mv ] ) ) {
674
								$m['value'][ $check_k ][ $mk ] = $frm_duplicate_ids[ $mv ];
675
		                    }
676
		                    unset($mk, $mv);
677
		                }
678
                    }
679
    		    }
680
		    }
681
		}
682
683
		if ( ! is_array($m['value']) ) {
684
		    $m['value'] = FrmAppHelper::maybe_json_decode($m['value']);
685
		}
686
687
		$post['postmeta'][ (string) $meta->meta_key ] = $m['value'];
0 ignored issues
show
introduced by
Detected usage of meta_key, possible slow query.
Loading history...
688
    }
689
690
    /**
691
     * Add terms to post
692
     * @param array $post by reference
693
     * @param object $item The XML object data
694
     */
695
    private static function populate_taxonomies( &$post, $item ) {
696
		foreach ( $item->category as $c ) {
697
			$att = $c->attributes();
698
			if ( ! isset( $att['nicename'] ) ) {
699
                continue;
700
            }
701
702
		    $taxonomy = (string) $att['domain'];
703
		    if ( is_taxonomy_hierarchical($taxonomy) ) {
0 ignored issues
show
Bug introduced by
The function is_taxonomy_hierarchical was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

703
		    if ( /** @scrutinizer ignore-call */ is_taxonomy_hierarchical($taxonomy) ) {
Loading history...
704
		        $name = (string) $att['nicename'];
705
		        $h_term = get_term_by('slug', $name, $taxonomy);
0 ignored issues
show
Bug introduced by
The function get_term_by was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

705
		        $h_term = /** @scrutinizer ignore-call */ get_term_by('slug', $name, $taxonomy);
Loading history...
706
		        if ( $h_term ) {
707
		            $name = $h_term->term_id;
708
		        }
709
		        unset($h_term);
710
		    } else {
711
		        $name = (string) $c;
712
		    }
713
714
			if ( ! isset( $post['tax_input'][ $taxonomy ] ) ) {
715
				$post['tax_input'][ $taxonomy ] = array();
716
			}
717
718
			$post['tax_input'][ $taxonomy ][] = $name;
719
		    unset($name);
720
		}
721
    }
722
723
    /**
724
     * Edit post if the key and created time match
725
     */
726
    private static function maybe_editing_post( &$post ) {
727
		$match_by = array(
728
		    'post_type'     => $post['post_type'],
729
		    'name'          => $post['post_name'],
730
		    'post_status'   => $post['post_status'],
731
		    'posts_per_page' => 1,
732
		);
733
734
		if ( in_array( $post['post_status'], array( 'trash', 'draft' ) ) ) {
735
		    $match_by['include'] = $post['post_id'];
736
		    unset($match_by['name']);
737
		}
738
739
		$editing = get_posts($match_by);
0 ignored issues
show
Bug introduced by
The function get_posts was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

739
		$editing = /** @scrutinizer ignore-call */ get_posts($match_by);
Loading history...
740
741
        if ( ! empty($editing) && current($editing)->post_date == $post['post_date'] ) {
742
            // set the id of the post to edit
743
            $post['ID'] = current($editing)->ID;
744
        }
745
    }
746
747
    private static function update_postmeta( &$post, $post_id ) {
748
        foreach ( $post['postmeta'] as $k => $v ) {
749
            if ( '_edit_last' == $k ) {
750
                $v = FrmAppHelper::get_user_id_param($v);
751
            } else if ( '_thumbnail_id' == $k && FrmAppHelper::pro_is_installed() ) {
752
                //change the attachment ID
753
				$field_obj = FrmFieldFactory::get_field_type( 'file' );
754
				$v = $field_obj->get_file_id( $v );
0 ignored issues
show
Bug introduced by
The method get_file_id() does not exist on stdClass. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

754
				/** @scrutinizer ignore-call */ 
755
    $v = $field_obj->get_file_id( $v );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
755
            }
756
757
            update_post_meta($post_id, $k, $v);
0 ignored issues
show
Bug introduced by
The function update_post_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

757
            /** @scrutinizer ignore-call */ 
758
            update_post_meta($post_id, $k, $v);
Loading history...
758
759
            unset($k, $v);
760
        }
761
    }
762
763
	/**
764
	 * If a template includes custom css, let's include it.
765
	 * The custom css is included on the default style.
766
	 *
767
	 * @since 2.03
768
	 */
769
	private static function maybe_update_custom_css( $custom_css ) {
770
		if ( empty( $custom_css ) ) {
771
			return;
772
		}
773
774
		$frm_style = new FrmStyle();
775
		$default_style = $frm_style->get_default_style();
776
		$default_style->post_content['custom_css'] .= "\r\n\r\n" . $custom_css;
777
		$frm_style->save( $default_style );
778
	}
779
780
	private static function maybe_update_stylesheet( $imported ) {
781
		$new_styles = isset( $imported['imported']['styles'] ) && ! empty( $imported['imported']['styles'] );
782
		$updated_styles = isset( $imported['updated']['styles'] ) && ! empty( $imported['updated']['styles'] );
783
		if ( $new_styles || $updated_styles ) {
784
			if ( is_admin() && function_exists( 'get_filesystem_method' ) ) {
0 ignored issues
show
Bug introduced by
The function is_admin was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

784
			if ( /** @scrutinizer ignore-call */ is_admin() && function_exists( 'get_filesystem_method' ) ) {
Loading history...
785
				$frm_style = new FrmStyle();
786
				$frm_style->update( 'default' );
787
			}
788
			foreach ( $imported['forms'] as $form_id ) {
789
				self::update_custom_style_setting_after_import( $form_id );
790
			}
791
		}
792
	}
793
794
    /**
795
     * @param string $message
796
     */
797
	public static function parse_message( $result, &$message, &$errors ) {
798
        if ( is_wp_error($result) ) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

798
        if ( /** @scrutinizer ignore-call */ is_wp_error($result) ) {
Loading history...
799
            $errors[] = $result->get_error_message();
800
        } else if ( ! $result ) {
801
            return;
802
        }
803
804
        if ( ! is_array($result) ) {
805
            $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...
806
            return;
807
        }
808
809
        $t_strings = array(
810
            'imported'  => __( 'Imported', 'formidable' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

810
            'imported'  => /** @scrutinizer ignore-call */ __( 'Imported', 'formidable' ),
Loading history...
811
            'updated'   => __( 'Updated', 'formidable' ),
812
        );
813
814
        $message = '<ul>';
815
        foreach ( $result as $type => $results ) {
816
			if ( ! isset( $t_strings[ $type ] ) ) {
817
                // only print imported and updated
818
                continue;
819
            }
820
821
            $s_message = array();
822
            foreach ( $results as $k => $m ) {
823
                self::item_count_message($m, $k, $s_message);
824
                unset($k, $m);
825
            }
826
827
            if ( ! empty($s_message) ) {
828
				$message .= '<li><strong>' . $t_strings[ $type ] . ':</strong> ';
829
                $message .= implode(', ', $s_message);
830
                $message .= '</li>';
831
            }
832
        }
833
834
        if ( $message == '<ul>' ) {
835
            $message = '';
836
            $errors[] = __( 'Nothing was imported or updated', 'formidable' );
837
        } else {
838
            $message .= '</ul>';
839
        }
840
    }
841
842
	public static function item_count_message( $m, $type, &$s_message ) {
843
        if ( ! $m ) {
844
            return;
845
        }
846
847
        $strings = array(
848
            'forms'     => sprintf( _n( '%1$s Form', '%1$s Forms', $m, 'formidable' ), $m ),
0 ignored issues
show
Bug introduced by
The function _n was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

848
            'forms'     => sprintf( /** @scrutinizer ignore-call */ _n( '%1$s Form', '%1$s Forms', $m, 'formidable' ), $m ),
Loading history...
849
            'fields'    => sprintf( _n( '%1$s Field', '%1$s Fields', $m, 'formidable' ), $m ),
850
            'items'     => sprintf( _n( '%1$s Entry', '%1$s Entries', $m, 'formidable' ), $m ),
851
            'views'     => sprintf( _n( '%1$s View', '%1$s Views', $m, 'formidable' ), $m ),
852
            'posts'     => sprintf( _n( '%1$s Post', '%1$s Posts', $m, 'formidable' ), $m ),
853
            'styles'     => sprintf( _n( '%1$s Style', '%1$s Styles', $m, 'formidable' ), $m ),
854
            'terms'     => sprintf( _n( '%1$s Term', '%1$s Terms', $m, 'formidable' ), $m ),
855
            'actions'   => sprintf( _n( '%1$s Form Action', '%1$s Form Actions', $m, 'formidable' ), $m ),
856
        );
857
858
		$s_message[] = isset( $strings[ $type ] ) ? $strings[ $type ] : ' ' . $m . ' ' . ucfirst( $type );
859
    }
860
861
	/**
862
	 * Prepare the form options for export
863
	 *
864
	 * @since 2.0.19
865
	 * @param string $options
866
	 * @return string
867
	 */
868
	public static function prepare_form_options_for_export( $options ) {
869
		$options = maybe_unserialize( $options );
0 ignored issues
show
Bug introduced by
The function maybe_unserialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

869
		$options = /** @scrutinizer ignore-call */ maybe_unserialize( $options );
Loading history...
870
		// Change custom_style to the post_name instead of ID
871
		if ( isset( $options['custom_style'] ) && 1 !== $options['custom_style'] ) {
872
			global $wpdb;
873
			$table = $wpdb->prefix . 'posts';
874
			$where = array( 'ID' => $options['custom_style'] );
875
			$select = 'post_name';
876
877
			$style_name = FrmDb::get_var( $table, $where, $select );
878
879
			if ( $style_name ) {
880
				$options['custom_style'] = $style_name;
881
			} else {
882
				$options['custom_style'] = 1;
883
			}
884
		}
885
		$options = serialize( $options );
886
		return self::cdata( $options );
887
	}
888
889
	public static function cdata( $str ) {
890
	    $str = maybe_unserialize($str);
0 ignored issues
show
Bug introduced by
The function maybe_unserialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

890
	    $str = /** @scrutinizer ignore-call */ maybe_unserialize($str);
Loading history...
891
	    if ( is_array($str) ) {
892
	        $str = json_encode($str);
893
		} else if ( seems_utf8( $str ) == false ) {
0 ignored issues
show
Bug introduced by
The function seems_utf8 was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

893
		} else if ( /** @scrutinizer ignore-call */ seems_utf8( $str ) == false ) {
Loading history...
894
			$str = utf8_encode( $str );
895
		}
896
897
        if ( is_numeric($str) ) {
898
            return $str;
899
        }
900
901
		self::remove_invalid_characters_from_xml( $str );
902
903
		// $str = ent2ncr(esc_html($str));
904
		$str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>';
905
906
		return $str;
907
	}
908
909
	/**
910
	 * Remove <US> character (unit separator) from exported strings
911
	 *
912
	 * @since 2.0.22
913
	 * @param string $str
914
	 */
915
	private static function remove_invalid_characters_from_xml( &$str ) {
916
		// Remove <US> character
917
		$str = str_replace( '\x1F', '', $str );
918
	}
919
920
    public static function migrate_form_settings_to_actions( $form_options, $form_id, &$imported = array(), $switch = false ) {
921
        // Get post type
922
        $post_type = FrmFormActionsController::$action_post_type;
923
924
        // Set up imported index, if not set up yet
925
        if ( ! isset( $imported['imported']['actions'] ) ) {
926
            $imported['imported']['actions'] = 0;
927
        }
928
929
        // Migrate post settings to action
930
        self::migrate_post_settings_to_action( $form_options, $form_id, $post_type, $imported, $switch );
931
932
        // Migrate email settings to action
933
        self::migrate_email_settings_to_action( $form_options, $form_id, $post_type, $imported, $switch );
934
    }
935
936
    /**
937
    * Migrate post settings to form action
938
    *
939
    * @param string $post_type
940
    */
941
    private static function migrate_post_settings_to_action( $form_options, $form_id, $post_type, &$imported, $switch ) {
942
        if ( ! isset($form_options['create_post']) || ! $form_options['create_post'] ) {
943
            return;
944
        }
945
946
        $new_action = array(
947
            'post_type'     => $post_type,
948
            'post_excerpt'  => 'wppost',
949
			'post_title'    => __( 'Create Posts', 'formidable' ),
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

949
			'post_title'    => /** @scrutinizer ignore-call */ __( 'Create Posts', 'formidable' ),
Loading history...
950
            'menu_order'    => $form_id,
951
            'post_status'   => 'publish',
952
            'post_content'  => array(),
953
			'post_name'     => $form_id . '_wppost_1',
954
        );
955
956
		$post_settings = array( 'post_type', 'post_category', 'post_content', 'post_excerpt', 'post_title', 'post_name', 'post_date', 'post_status', 'post_custom_fields', 'post_password' );
957
958
        foreach ( $post_settings as $post_setting ) {
959
			if ( isset( $form_options[ $post_setting ] ) ) {
960
				$new_action['post_content'][ $post_setting ] = $form_options[ $post_setting ];
961
            }
962
            unset($post_setting);
963
        }
964
965
		$new_action['event'] = array( 'create', 'update' );
966
967
        if ( $switch ) {
968
			// Fields with string or int saved
969
			$basic_fields = array( 'post_title', 'post_content', 'post_excerpt', 'post_password', 'post_date', 'post_status' );
970
971
			// Fields with arrays saved
972
			$array_fields = array( 'post_category', 'post_custom_fields' );
973
974
			$new_action['post_content'] = self::switch_action_field_ids( $new_action['post_content'], $basic_fields, $array_fields );
975
        }
976
        $new_action['post_content'] = json_encode($new_action['post_content']);
977
978
        $exists = get_posts( array(
0 ignored issues
show
Bug introduced by
The function get_posts was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

978
        $exists = /** @scrutinizer ignore-call */ get_posts( array(
Loading history...
979
            'name'          => $new_action['post_name'],
980
            'post_type'     => $new_action['post_type'],
981
            'post_status'   => $new_action['post_status'],
982
            'numberposts'   => 1,
983
        ) );
984
985
        if ( ! $exists ) {
986
			// this isn't an email, but we need to use a class that will always be included
987
			FrmDb::save_json_post( $new_action );
988
            $imported['imported']['actions']++;
989
        }
990
    }
991
992
	/**
993
	 * Switch old field IDs for new field IDs in emails and post
994
	 *
995
	 * @since 2.0
996
	 * @param array $post_content - check for old field IDs
997
	 * @param array $basic_fields - fields with string or int saved
998
	 * @param array $array_fields - fields with arrays saved
999
	 *
1000
	 * @return string $post_content - new field IDs
1001
	 */
1002
	private static function switch_action_field_ids( $post_content, $basic_fields, $array_fields = array() ) {
1003
        global $frm_duplicate_ids;
1004
1005
        // If there aren't IDs that were switched, end now
1006
        if ( ! $frm_duplicate_ids ) {
1007
            return;
1008
        }
1009
1010
        // Get old IDs
1011
        $old = array_keys( $frm_duplicate_ids );
1012
1013
        // Get new IDs
1014
        $new = array_values( $frm_duplicate_ids );
1015
1016
        // Do a str_replace with each item to set the new IDs
1017
        foreach ( $post_content as $key => $setting ) {
1018
            if ( ! is_array( $setting ) && in_array( $key, $basic_fields ) ) {
1019
                // Replace old IDs with new IDs
1020
				$post_content[ $key ] = str_replace( $old, $new, $setting );
1021
            } else if ( is_array( $setting ) && in_array( $key, $array_fields ) ) {
1022
                foreach ( $setting as $k => $val ) {
1023
                    // Replace old IDs with new IDs
1024
					$post_content[ $key ][ $k ] = str_replace( $old, $new, $val );
1025
                }
1026
            }
1027
            unset( $key, $setting );
1028
        }
1029
        return $post_content;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $post_content returns the type array<mixed,mixed>|array which is incompatible with the documented return type string.
Loading history...
1030
    }
1031
1032
    private static function migrate_email_settings_to_action( $form_options, $form_id, $post_type, &$imported, $switch ) {
1033
        // No old notifications or autoresponders to carry over
1034
		if ( ! isset( $form_options['auto_responder'] ) && ! isset( $form_options['notification'] ) && ! isset( $form_options['email_to'] ) ) {
1035
            return;
1036
        }
1037
1038
        // Initialize notifications array
1039
        $notifications = array();
1040
1041
        // Migrate regular notifications
1042
        self::migrate_notifications_to_action( $form_options, $form_id, $notifications );
1043
1044
        // Migrate autoresponders
1045
        self::migrate_autoresponder_to_action( $form_options, $form_id, $notifications );
1046
1047
        if ( empty( $notifications ) ) {
1048
            return;
1049
        }
1050
1051
        foreach ( $notifications as $new_notification ) {
1052
            $new_notification['post_type']      = $post_type;
1053
            $new_notification['post_excerpt']   = 'email';
1054
			$new_notification['post_title']     = __( 'Email Notification', 'formidable' );
0 ignored issues
show
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1054
			$new_notification['post_title']     = /** @scrutinizer ignore-call */ __( 'Email Notification', 'formidable' );
Loading history...
1055
            $new_notification['menu_order']     = $form_id;
1056
            $new_notification['post_status']    = 'publish';
1057
1058
            // Switch field IDs and keys, if needed
1059
            if ( $switch ) {
1060
1061
				// Switch field IDs in email conditional logic
1062
				self::switch_email_contition_field_ids( $new_notification['post_content'] );
1063
1064
				// Switch all other field IDs in email
1065
                $new_notification['post_content'] = FrmFieldsHelper::switch_field_ids( $new_notification['post_content'] );
1066
            }
1067
            $new_notification['post_content']   = FrmAppHelper::prepare_and_encode( $new_notification['post_content'] );
1068
1069
            $exists = get_posts( array(
0 ignored issues
show
Bug introduced by
The function get_posts was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1069
            $exists = /** @scrutinizer ignore-call */ get_posts( array(
Loading history...
1070
                'name'          => $new_notification['post_name'],
1071
                'post_type'     => $new_notification['post_type'],
1072
                'post_status'   => $new_notification['post_status'],
1073
                'numberposts'   => 1,
1074
            ) );
1075
1076
            if ( empty($exists) ) {
1077
				FrmDb::save_json_post( $new_notification );
1078
                $imported['imported']['actions']++;
1079
            }
1080
            unset($new_notification);
1081
        }
1082
1083
		self::remove_deprecated_notification_settings( $form_id, $form_options );
1084
    }
1085
1086
	/**
1087
	 * Remove deprecated notification settings after migration
1088
	 *
1089
	 * @since 2.05
1090
	 *
1091
	 * @param int|string $form_id
1092
	 * @param array $form_options
1093
	 */
1094
	private static function remove_deprecated_notification_settings( $form_id, $form_options ) {
1095
		$delete_settings = array( 'notification', 'autoresponder', 'email_to' );
1096
		foreach ( $delete_settings as $index ) {
1097
			if ( isset( $form_options[ $index ] ) ) {
1098
				unset( $form_options[ $index ] );
1099
			}
1100
		}
1101
		FrmForm::update( $form_id, array( 'options' => $form_options ) );
1102
	}
1103
1104
    private static function migrate_notifications_to_action( $form_options, $form_id, &$notifications ) {
1105
        if ( ! isset( $form_options['notification'] ) && isset( $form_options['email_to'] ) && ! empty( $form_options['email_to'] ) ) {
1106
            // add old settings into notification array
1107
			$form_options['notification'] = array( 0 => $form_options );
1108
        } else if ( isset( $form_options['notification']['email_to'] ) ) {
1109
            // make sure it's in the correct format
1110
			$form_options['notification'] = array( 0 => $form_options['notification'] );
1111
        }
1112
1113
        if ( isset( $form_options['notification'] ) && is_array($form_options['notification']) ) {
1114
            foreach ( $form_options['notification'] as $email_key => $notification ) {
1115
1116
				$atts = array(
1117
					'email_to'  => '',
1118
					'reply_to'  => '',
1119
					'reply_to_name' => '',
1120
					'event'     => '',
1121
					'form_id'   => $form_id,
1122
					'email_key' => $email_key,
1123
				);
1124
1125
                // Format the email data
1126
                self::format_email_data( $atts, $notification );
1127
1128
				if ( isset( $notification['twilio'] ) && $notification['twilio'] ) {
1129
					do_action( 'frm_create_twilio_action', $atts, $notification );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1129
					/** @scrutinizer ignore-call */ 
1130
     do_action( 'frm_create_twilio_action', $atts, $notification );
Loading history...
1130
				}
1131
1132
                // Setup the new notification
1133
                $new_notification = array();
1134
                self::setup_new_notification( $new_notification, $notification, $atts );
1135
1136
                $notifications[] = $new_notification;
1137
            }
1138
        }
1139
    }
1140
1141
    private static function format_email_data( &$atts, $notification ) {
1142
        // Format email_to
1143
        self::format_email_to_data( $atts, $notification );
1144
1145
        // Format the reply to email and name
1146
		$reply_fields = array(
1147
			'reply_to'      => '',
1148
			'reply_to_name' => '',
1149
		);
1150
        foreach ( $reply_fields as $f => $val ) {
1151
			if ( isset( $notification[ $f ] ) ) {
1152
				$atts[ $f ] = $notification[ $f ];
1153
				if ( 'custom' == $notification[ $f ] ) {
1154
					$atts[ $f ] = $notification[ 'cust_' . $f ];
1155
				} else if ( is_numeric( $atts[ $f ] ) && ! empty( $atts[ $f ] ) ) {
1156
					$atts[ $f ] = '[' . $atts[ $f ] . ']';
1157
                }
1158
            }
1159
            unset( $f, $val );
1160
        }
1161
1162
        // Format event
1163
		$atts['event'] = array( 'create' );
1164
        if ( isset( $notification['update_email'] ) && 1 == $notification['update_email'] ) {
1165
            $atts['event'][] = 'update';
1166
        } else if ( isset($notification['update_email']) && 2 == $notification['update_email'] ) {
1167
			$atts['event'] = array( 'update' );
1168
        }
1169
    }
1170
1171
    private static function format_email_to_data( &$atts, $notification ) {
1172
        if ( isset( $notification['email_to'] ) ) {
1173
			$atts['email_to'] = preg_split( '/ (,|;) /', $notification['email_to'] );
1174
        } else {
1175
            $atts['email_to'] = array();
1176
        }
1177
1178
        if ( isset( $notification['also_email_to'] ) ) {
1179
            $email_fields = (array) $notification['also_email_to'];
1180
            $atts['email_to'] = array_merge( $email_fields, $atts['email_to'] );
1181
            unset( $email_fields );
1182
        }
1183
1184
        foreach ( $atts['email_to'] as $key => $email_field ) {
1185
1186
            if ( is_numeric( $email_field ) ) {
1187
				$atts['email_to'][ $key ] = '[' . $email_field . ']';
1188
            }
1189
1190
            if ( strpos( $email_field, '|') ) {
1191
                $email_opt = explode( '|', $email_field );
1192
                if ( isset( $email_opt[0] ) ) {
1193
					$atts['email_to'][ $key ] = '[' . $email_opt[0] . ' show=' . $email_opt[1] . ']';
1194
                }
1195
                unset( $email_opt );
1196
            }
1197
        }
1198
        $atts['email_to'] = implode(', ', $atts['email_to']);
1199
    }
1200
1201
    private static function setup_new_notification( &$new_notification, $notification, $atts ) {
1202
        // Set up new notification
1203
        $new_notification = array(
1204
            'post_content'  => array(
1205
                'email_to'      => $atts['email_to'],
1206
                'event'         => $atts['event'],
1207
            ),
1208
			'post_name'         => $atts['form_id'] . '_email_' . $atts['email_key'],
1209
        );
1210
1211
        // Add more fields to the new notification
1212
        $add_fields = array( 'email_message', 'email_subject', 'plain_text', 'inc_user_info', 'conditions' );
1213
        foreach ( $add_fields as $add_field ) {
1214
			if ( isset( $notification[ $add_field ] ) ) {
1215
				$new_notification['post_content'][ $add_field ] = $notification[ $add_field ];
1216
            } else if ( in_array( $add_field, array( 'plain_text', 'inc_user_info' ) ) ) {
1217
				$new_notification['post_content'][ $add_field ] = 0;
1218
            } else {
1219
				$new_notification['post_content'][ $add_field ] = '';
1220
            }
1221
            unset( $add_field );
1222
        }
1223
1224
		// Set reply to
1225
		$new_notification['post_content']['reply_to'] = $atts['reply_to'];
1226
1227
        // Set from
1228
		if ( ! empty( $atts['reply_to'] ) || ! empty( $atts['reply_to_name'] ) ) {
1229
			$new_notification['post_content']['from'] = ( empty( $atts['reply_to_name'] ) ? '[sitename]' : $atts['reply_to_name'] ) . ' <' . ( empty( $atts['reply_to'] ) ? '[admin_email]' : $atts['reply_to'] ) . '>';
1230
        }
1231
    }
1232
1233
	/**
1234
	* Switch field IDs in pre-2.0 email conditional logic
1235
	*
1236
	* @param $post_content array, pass by reference
1237
	*/
1238
	private static function switch_email_contition_field_ids( &$post_content ) {
1239
		// Switch field IDs in conditional logic
1240
		if ( isset( $post_content['conditions'] ) && is_array( $post_content['conditions'] ) ) {
1241
			foreach ( $post_content['conditions'] as $email_key => $val ) {
1242
				if ( is_numeric( $email_key ) ) {
1243
					$post_content['conditions'][ $email_key ] = self::switch_action_field_ids( $val, array( 'hide_field' ) );
1244
				}
1245
				unset( $email_key, $val);
1246
			}
1247
		}
1248
	}
1249
1250
    private static function migrate_autoresponder_to_action( $form_options, $form_id, &$notifications ) {
1251
        if ( isset($form_options['auto_responder']) && $form_options['auto_responder'] && isset($form_options['ar_email_message']) && $form_options['ar_email_message'] ) {
1252
            // migrate autoresponder
1253
1254
            $email_field = isset($form_options['ar_email_to']) ? $form_options['ar_email_to'] : 0;
1255
            if ( strpos($email_field, '|') ) {
1256
                // data from entries field
1257
                $email_field = explode('|', $email_field);
1258
                if ( isset($email_field[1]) ) {
1259
                    $email_field = $email_field[1];
1260
                }
1261
            }
1262
            if ( is_numeric($email_field) && ! empty($email_field) ) {
1263
				$email_field = '[' . $email_field . ']';
1264
            }
1265
1266
            $notification = $form_options;
1267
            $new_notification2 = array(
1268
                'post_content'  => array(
1269
                    'email_message' => $notification['ar_email_message'],
1270
                    'email_subject' => isset($notification['ar_email_subject']) ? $notification['ar_email_subject'] : '',
1271
                    'email_to'      => $email_field,
1272
                    'plain_text'    => isset($notification['ar_plain_text']) ? $notification['ar_plain_text'] : 0,
1273
                    'inc_user_info' => 0,
1274
                ),
1275
				'post_name'     => $form_id . '_email_' . count( $notifications ),
1276
            );
1277
1278
            $reply_to = isset($notification['ar_reply_to']) ? $notification['ar_reply_to'] : '';
1279
            $reply_to_name = isset($notification['ar_reply_to_name']) ? $notification['ar_reply_to_name'] : '';
1280
1281
			if ( ! empty( $reply_to ) ) {
1282
				$new_notification2['post_content']['reply_to'] = $reply_to;
1283
			}
1284
1285
			if ( ! empty( $reply_to ) || ! empty( $reply_to_name ) ) {
1286
				$new_notification2['post_content']['from'] = ( empty( $reply_to_name ) ? '[sitename]' : $reply_to_name ) . ' <' . ( empty( $reply_to ) ? '[admin_email]' : $reply_to ) . '>';
1287
			}
1288
1289
            $notifications[] = $new_notification2;
1290
            unset( $new_notification2 );
1291
        }
1292
    }
1293
}
1294
1295