Completed
Push — master ( 6ba0c4...a7a5ee )
by Stephanie
03:13
created

FrmEntry::create_entry()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 2
dl 0
loc 12
rs 9.4285
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 FrmEntry {
7
8
	/**
9
	* Create a new entry
10
	*
11
	* @param array $values
12
	* @return int | boolean $entry_id
13
	*/
14
	public static function create( $values ) {
15
		$entry_id = self::create_entry( $values, 'standard' );
16
17
		return $entry_id;
18
	}
19
20
	/**
21
	* Create a new entry with some differences depending on type
22
	*
23
	* @param array $values
24
	* @param string $type
25
	* @return int | boolean $entry_id
26
	*/
27
	private static function create_entry( $values, $type ) {
28
		$new_values = self::before_insert_entry_in_database( $values, $type );
29
30
		// Don't check XML entries for duplicates
31
		if ( $type != 'xml' && self::is_duplicate( $new_values, $values ) ) {
32
			return false;
33
		}
34
35
		$entry_id = self::continue_to_create_entry( $values, $new_values );
36
37
		return $entry_id;
38
	}
39
40
    /**
41
     * check for duplicate entries created in the last minute
42
     * @return boolean
43
     */
44
	public static function is_duplicate( $new_values, $values ) {
45
		$duplicate_entry_time = apply_filters( 'frm_time_to_check_duplicates', 60, $new_values );
46
47
		if ( false === self::is_duplicate_check_needed( $values, $duplicate_entry_time ) ) {
48
			return false;
49
		}
50
51
        $check_val = $new_values;
52
		$check_val['created_at >'] = date( 'Y-m-d H:i:s', ( strtotime( $new_values['created_at'] ) - absint( $duplicate_entry_time ) ) );
53
54
		unset( $check_val['created_at'], $check_val['updated_at'] );
55
		unset( $check_val['is_draft'], $check_val['id'], $check_val['item_key'] );
56
57
        if ( $new_values['item_key'] == $new_values['name'] ) {
58
            unset($check_val['name']);
59
        }
60
61
        global $wpdb;
62
		$entry_exists = FrmDb::get_col( $wpdb->prefix . 'frm_items', $check_val, 'id', array( 'order_by' => 'created_at DESC' ) );
63
64
        if ( ! $entry_exists || empty($entry_exists) || ! isset($values['item_meta']) ) {
65
            return false;
66
        }
67
68
        $is_duplicate = false;
69
        foreach ( $entry_exists as $entry_exist ) {
0 ignored issues
show
Bug introduced by
The expression $entry_exists of type array|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
70
            $is_duplicate = true;
71
72
            //add more checks here to make sure it's a duplicate
73
            $metas = FrmEntryMeta::get_entry_meta_info($entry_exist);
74
            $field_metas = array();
75
            foreach ( $metas as $meta ) {
0 ignored issues
show
Bug introduced by
The expression $metas of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
76
				$field_metas[ $meta->field_id ] = $meta->meta_value;
77
            }
78
79
            // If prev entry is empty and current entry is not, they are not duplicates
80
            $filtered_vals = array_filter( $values['item_meta'] );
81
            if ( empty( $field_metas ) && ! empty( $filtered_vals ) ) {
82
                return false;
83
            }
84
85
            $diff = array_diff_assoc($field_metas, array_map('maybe_serialize', $values['item_meta']));
86
            foreach ( $diff as $field_id => $meta_value ) {
87
                if ( ! empty($meta_value) ) {
88
                    $is_duplicate = false;
89
                    continue;
90
                }
91
            }
92
93
            if ( $is_duplicate ) {
94
				break;
95
            }
96
        }
97
98
        return $is_duplicate;
99
    }
100
101
	/**
102
	 * Determine if an entry needs to be checked as a possible duplicate
103
	 *
104
	 * @since 2.0.23
105
	 * @param array $values
106
	 * @param int $duplicate_entry_time
107
	 * @return bool
108
	 */
109
	private static function is_duplicate_check_needed( $values, $duplicate_entry_time ) {
110
		// If time for checking duplicates is set to an empty value, don't check for duplicates
111
		if ( empty( $duplicate_entry_time ) ) {
112
			return false;
113
		}
114
115
		// If CSV is importing, don't check for duplicates
116
		if ( defined('WP_IMPORTING') && WP_IMPORTING ) {
117
			return false;
118
		}
119
120
		// If repeating field entries are getting created, don't check for duplicates
121
		if ( isset( $values['parent_form_id'] ) && $values['parent_form_id'] ) {
122
			return false;
123
		}
124
125
		return true;
126
	}
127
128
    public static function duplicate( $id ) {
129
        global $wpdb;
130
131
        $values = self::getOne( $id );
132
133
        $new_values = array();
134
		$new_values['item_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_items', 'item_key' );
135
        $new_values['name'] = $values->name;
136
        $new_values['is_draft'] = $values->is_draft;
137
		$new_values['user_id'] = (int) $values->user_id;
138
		$new_values['updated_by'] = (int) $values->user_id;
139
        $new_values['form_id'] = $values->form_id ? (int) $values->form_id: null;
140
		$new_values['created_at'] = current_time( 'mysql', 1 );
141
		$new_values['updated_at'] = $new_values['created_at'];
142
143
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
144
        if ( ! $query_results ) {
145
            return false;
146
        }
147
148
        $entry_id = $wpdb->insert_id;
149
150
        global $frm_vars;
151
        if ( ! isset($frm_vars['saved_entries']) ) {
152
            $frm_vars['saved_entries'] = array();
153
        }
154
        $frm_vars['saved_entries'][] = (int) $entry_id;
155
156
        FrmEntryMeta::duplicate_entry_metas($id, $entry_id);
157
		self::clear_cache();
158
159
		do_action( 'frm_after_duplicate_entry', $entry_id, $new_values['form_id'], array( 'old_id' => $id ) );
160
        return $entry_id;
161
    }
162
163
	/**
164
	* Update an entry (not via XML)
165
	*
166
	* @param int $id
167
	* @param array $values
168
	* @return boolean|int $update_results
169
	*/
170
	public static function update( $id, $values ) {
171
		$update_results = self::update_entry( $id, $values, 'standard' );
172
173
		return $update_results;
174
	}
175
176
	/**
177
	* Update an entry with some differences depending on the update type
178
	*
179
	* @since 2.0.16
180
	*
181
	* @param int $id
182
	* @param array $values
183
	* @return boolean|int $query_results
184
	*/
185
	private static function update_entry( $id, $values, $update_type ) {
186
		global $wpdb;
187
188
		$update = self::before_update_entry( $id, $values, $update_type );
189
		if ( ! $update ) {
190
			return false;
191
		}
192
193
		$new_values = self::package_entry_to_update( $id, $values );
194
195
		$query_results = $wpdb->update( $wpdb->prefix . 'frm_items', $new_values, compact('id') );
196
197
		self::after_update_entry( $query_results, $id, $values, $new_values );
198
199
		return $query_results;
200
	}
201
202
	public static function destroy( $id ) {
203
        global $wpdb;
204
        $id = (int) $id;
205
206
		$entry = self::getOne( $id );
207
        if ( ! $entry ) {
208
            $result = false;
209
            return $result;
210
        }
211
212
        do_action('frm_before_destroy_entry', $id, $entry);
213
214
		$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas WHERE item_id=%d', $id ) );
215
		$result = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_items WHERE id=%d', $id ) );
216
217
		self::clear_cache();
218
219
        return $result;
220
    }
221
222
	public static function update_form( $id, $value, $form_id ) {
223
        global $wpdb;
224
        $form_id = isset($value) ? $form_id : null;
225
		$result = $wpdb->update( $wpdb->prefix . 'frm_items', array( 'form_id' => $form_id ), array( 'id' => $id ) );
226
		if ( $result ) {
227
			self::clear_cache();
228
		}
229
        return $result;
230
    }
231
232
	/**
233
	 * Clear entry caching
234
	 * Called when an entry is changed
235
	 *
236
	 * @since 2.0.5
237
	 */
238
	public static function clear_cache() {
239
		FrmAppHelper::cache_delete_group( 'frm_entry' );
240
		FrmAppHelper::cache_delete_group( 'frm_item' );
241
		FrmAppHelper::cache_delete_group( 'frm_entry_meta' );
242
		FrmAppHelper::cache_delete_group( 'frm_item_meta' );
243
	}
244
245
	/**
246
	 * After switching to the wp_loaded hook for processing entries,
247
	 * we can no longer use 'name', but check it as a fallback
248
	 * @since 2.0.11
249
	 */
250
	public static function get_new_entry_name( $values, $default = '' ) {
251
		return isset( $values['item_name'] ) ? $values['item_name'] : ( isset( $values['name'] ) ? $values['name'] : $default );
252
	}
253
254
	/**
255
	 * If $entry is numeric, get the entry object
256
	 * @param int|object $entry by reference
257
	 * @since 2.0.9
258
	 */
259
	public static function maybe_get_entry( &$entry ) {
260
		if ( $entry && is_numeric( $entry ) ) {
261
			$entry = self::getOne( $entry );
262
		}
263
	}
264
265
	public static function getOne( $id, $meta = false ) {
0 ignored issues
show
Coding Style introduced by
The function name getOne is in camel caps, but expected get_one instead as per the coding standard.
Loading history...
266
        global $wpdb;
267
268
        $query = "SELECT it.*, fr.name as form_name, fr.form_key as form_key FROM {$wpdb->prefix}frm_items it
269
                  LEFT OUTER JOIN {$wpdb->prefix}frm_forms fr ON it.form_id=fr.id WHERE ";
270
271
        $query .= is_numeric($id) ? 'it.id=%d' : 'it.item_key=%s';
272
        $query_args = array( $id );
273
        $query = $wpdb->prepare( $query, $query_args );
274
275
        if ( ! $meta ) {
276
			$entry = FrmAppHelper::check_cache( $id . '_nometa', 'frm_entry', $query, 'get_row' );
277
            return stripslashes_deep($entry);
278
        }
279
280
        $entry = FrmAppHelper::check_cache( $id, 'frm_entry' );
281
        if ( $entry !== false ) {
282
            return stripslashes_deep($entry);
283
        }
284
285
        $entry = $wpdb->get_row( $query );
286
        $entry = self::get_meta($entry);
287
288
        return stripslashes_deep($entry);
289
    }
290
291
	public static function get_meta( $entry ) {
292
        if ( ! $entry ) {
293
            return $entry;
294
        }
295
296
        global $wpdb;
297
		$metas = FrmDb::get_results( $wpdb->prefix . 'frm_item_metas m LEFT JOIN ' . $wpdb->prefix . 'frm_fields f ON m.field_id=f.id', array( 'item_id' => $entry->id, 'field_id !' => 0 ), 'field_id, meta_value, field_key, item_id' );
298
299
        $entry->metas = array();
300
301
		$include_key = apply_filters( 'frm_include_meta_keys', false, array( 'form_id' => $entry->form_id ) );
302
        foreach ( $metas as $meta_val ) {
0 ignored issues
show
Bug introduced by
The expression $metas of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
303
            if ( $meta_val->item_id == $entry->id ) {
304
				$entry->metas[ $meta_val->field_id ] = maybe_unserialize( $meta_val->meta_value );
305
				if ( $include_key ) {
306
					$entry->metas[ $meta_val->field_key ] = $entry->metas[ $meta_val->field_id ];
307
				}
308
                 continue;
309
            }
310
311
            // include sub entries in an array
312
			if ( ! isset( $entry_metas[ $meta_val->field_id ] ) ) {
313
				$entry->metas[ $meta_val->field_id ] = array();
314
            }
315
316
			$entry->metas[ $meta_val->field_id ][] = maybe_unserialize( $meta_val->meta_value );
317
318
            unset($meta_val);
319
        }
320
        unset($metas);
321
322
		FrmAppHelper::set_cache( $entry->id, $entry, 'frm_entry' );
323
324
        return $entry;
325
    }
326
327
    /**
328
     * @param string $id
329
     */
330
	public static function exists( $id ) {
331
        global $wpdb;
332
333
        if ( FrmAppHelper::check_cache( $id, 'frm_entry' ) ) {
334
            $exists = true;
335
            return $exists;
336
        }
337
338
        if ( is_numeric($id) ) {
339
            $where = array( 'id' => $id );
340
        } else {
341
            $where = array( 'item_key' => $id );
342
        }
343
		$id = FrmDb::get_var( $wpdb->prefix . 'frm_items', $where );
344
345
        $exists = ($id && $id > 0) ? true : false;
346
        return $exists;
347
    }
348
349
    public static function getAll( $where, $order_by = '', $limit = '', $meta = false, $inc_form = true ) {
0 ignored issues
show
Coding Style introduced by
The function name getAll is in camel caps, but expected get_all instead as per the coding standard.
Loading history...
350
		global $wpdb;
351
352
        $limit = FrmAppHelper::esc_limit($limit);
353
354
        $cache_key = maybe_serialize($where) . $order_by . $limit . $inc_form;
355
        $entries = wp_cache_get($cache_key, 'frm_entry');
356
357
        if ( false === $entries ) {
358
            $fields = 'it.id, it.item_key, it.name, it.ip, it.form_id, it.post_id, it.user_id, it.parent_item_id, it.updated_by, it.created_at, it.updated_at, it.is_draft';
359
			$table = $wpdb->prefix . 'frm_items it ';
360
361
            if ( $inc_form ) {
362
                $fields = 'it.*, fr.name as form_name,fr.form_key as form_key';
363
                $table .= 'LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id ';
364
            }
365
366
            if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) {
367
    		    // sort by a requested field
368
                $field_id = (int) $order_matches[1];
369
				$fields .= ', (SELECT meta_value FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id = ' . $field_id . ' AND item_id = it.id) as meta_' . $field_id;
370
				unset( $order_matches, $field_id );
371
		    }
372
373
			// prepare the query
374
			$query = 'SELECT ' . $fields . ' FROM ' . $table . FrmAppHelper::prepend_and_or_where(' WHERE ', $where) . $order_by . $limit;
375
376
            $entries = $wpdb->get_results($query, OBJECT_K);
377
            unset($query);
378
379
			FrmAppHelper::set_cache( $cache_key, $entries, 'frm_entry' );
380
        }
381
382
        if ( ! $meta || ! $entries ) {
383
            return stripslashes_deep($entries);
384
        }
385
        unset($meta);
386
387
        if ( ! is_array( $where ) && preg_match('/^it\.form_id=\d+$/', $where) ) {
388
			$where = array( 'it.form_id' => substr( $where, 11 ) );
389
        }
390
391
        $meta_where = array( 'field_id !' => 0 );
392
        if ( $limit == '' && is_array($where) && count($where) == 1 && isset($where['it.form_id']) ) {
393
            $meta_where['fi.form_id'] = $where['it.form_id'];
394
        } else {
395
            $meta_where['item_id'] = array_keys( $entries );
396
        }
397
398
        $metas = FrmDb::get_results( $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON (it.field_id = fi.id)', $meta_where, 'item_id, meta_value, field_id, field_key, form_id' );
399
400
        unset( $meta_where );
401
402
        if ( ! $metas ) {
403
            return stripslashes_deep($entries);
404
        }
405
406
        foreach ( $metas as $m_key => $meta_val ) {
0 ignored issues
show
Bug introduced by
The expression $metas of type array|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
407
            if ( ! isset( $entries[ $meta_val->item_id ] ) ) {
408
                continue;
409
            }
410
411
            if ( ! isset( $entries[ $meta_val->item_id ]->metas ) ) {
412
				$entries[ $meta_val->item_id ]->metas = array();
413
            }
414
415
			$entries[ $meta_val->item_id ]->metas[ $meta_val->field_id ] = maybe_unserialize( $meta_val->meta_value );
416
417
            unset($m_key, $meta_val);
418
        }
419
420
		if ( ! FrmAppHelper::prevent_caching() ) {
421
			foreach ( $entries as $entry ) {
422
				FrmAppHelper::set_cache( $entry->id, $entry, 'frm_entry' );
423
				unset( $entry );
424
			}
425
		}
426
427
        return stripslashes_deep($entries);
428
    }
429
430
    // Pagination Methods
431
    public static function getRecordCount( $where = '' ) {
0 ignored issues
show
Coding Style introduced by
The function name getRecordCount is in camel caps, but expected get_record_count instead as per the coding standard.
Loading history...
432
        global $wpdb;
433
		$table_join = $wpdb->prefix . 'frm_items it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id';
434
435
        if ( is_numeric($where) ) {
436
            $table_join = 'frm_items';
437
            $where = array( 'form_id' => $where );
438
        }
439
440
        if ( is_array( $where ) ) {
441
            $count = FrmDb::get_count( $table_join, $where );
442
        } else {
443
			$cache_key = 'count_' . maybe_serialize( $where );
444
			$query = 'SELECT COUNT(*) FROM ' . $table_join . FrmAppHelper::prepend_and_or_where( ' WHERE ', $where );
445
			$count = FrmAppHelper::check_cache( $cache_key, 'frm_entry', $query, 'get_var' );
446
        }
447
448
        return $count;
449
    }
450
451
    public static function getPageCount( $p_size, $where = '' ) {
0 ignored issues
show
Coding Style introduced by
The function name getPageCount is in camel caps, but expected get_page_count instead as per the coding standard.
Loading history...
452
		$p_size = (int) $p_size;
453
		$count = 1;
454
		if ( $p_size ) {
455
			if ( ! is_numeric( $where ) ) {
456
				$where = self::getRecordCount( $where );
457
			}
458
			$count = ceil( (int) $where / $p_size );
459
		}
460
461
		return $count;
462
    }
463
464
	/**
465
	* Prepare the data before inserting it into the database
466
	*
467
	* @since 2.0.16
468
	* @param array $values
469
	* @param string $type
470
	* @return array $new_values
471
	*/
472
	private static function before_insert_entry_in_database( &$values, $type ) {
473
474
		self::sanitize_entry_post( $values );
475
476
		if ( $type != 'xml' ) {
477
			$values = apply_filters('frm_pre_create_entry', $values);
478
		}
479
480
		$new_values = self::package_entry_data( $values );
481
482
		return $new_values;
483
	}
484
485
	/**
486
	* Create an entry and perform after create actions
487
	*
488
	* @since 2.0.16
489
	* @param array $values
490
	* @param array $new_values
491
	* @return boolean|int $entry_id
492
	*/
493
	private static function continue_to_create_entry( $values, $new_values ) {
494
		$entry_id = self::insert_entry_into_database( $new_values );
495
		if ( ! $entry_id ) {
496
			return false;
497
		}
498
499
		self::after_insert_entry_in_database( $values, $new_values, $entry_id );
500
501
		return $entry_id;
502
	}
503
504
    /**
505
     * Sanitize the POST values before we use them
506
     *
507
     * @since 2.0
508
     * @param array $values The POST values by reference
509
     */
510
    public static function sanitize_entry_post( &$values ) {
511
        $sanitize_method = array(
512
            'form_id'       => 'absint',
513
            'frm_action'    => 'sanitize_title',
514
            'form_key'      => 'sanitize_title',
515
            'item_key'      => 'sanitize_title',
516
            'item_name'     => 'sanitize_text_field',
517
            'frm_saving_draft' => 'absint',
518
            'is_draft'      => 'absint',
519
            'post_id'       => 'absint',
520
            'parent_item_id' => 'absint',
521
            'created_at'    => 'sanitize_text_field',
522
            'updated_at'    => 'sanitize_text_field',
523
        );
524
525
        FrmAppHelper::sanitize_request( $sanitize_method, $values );
526
    }
527
528
	/**
529
	* Prepare the new values for inserting into the database
530
	*
531
	* @since 2.0.16
532
	* @param array $values
533
	* @return array $new_values
534
	*/
535
	private static function package_entry_data( &$values ) {
536
		global $wpdb;
537
538
		if ( ! isset( $values['item_key'] ) ) {
539
			$values['item_key'] = '';
540
		}
541
542
		$item_name = self::get_new_entry_name( $values, $values['item_key'] );
543
		$new_values = array(
544
			'item_key'  => FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key' ),
545
			'name'      => FrmAppHelper::truncate( $item_name, 255, 1, '' ),
546
			'ip'        => self::get_ip( $values ),
547
			'is_draft'  => self::get_is_draft_value( $values ),
548
			'form_id'   => self::get_form_id( $values ),
549
			'post_id'   => self::get_post_id( $values ),
550
			'parent_item_id' => self::get_parent_item_id( $values ),
551
			'created_at' => self::get_created_at( $values ),
552
			'updated_at' => self::get_updated_at( $values ),
553
			'description' => self::get_entry_description( $values ),
554
			'user_id' => self::get_entry_user_id( $values ),
555
		);
556
557
		if ( is_array($new_values['name']) ) {
558
			$new_values['name'] = reset($new_values['name']);
559
		}
560
561
		$new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
562
563
		return $new_values;
564
	}
565
566
	/**
567
	 * Get the ip for a new entry.
568
	 * Allow the import to override the value.
569
	 *
570
	 * @since 2.03.10
571
	 * @param array $values
572
	 * @return string
573
	 */
574
	private static function get_ip( $values ) {
575
		$ip = FrmAppHelper::get_ip_address();
576
		if ( defined('WP_IMPORTING') && WP_IMPORTING ) {
577
			$ip = isset( $values['ip'] ) ? $values['ip'] : $ip;
578
		}
579
		return $ip;
580
	}
581
582
	/**
583
	* Get the is_draft value for a new entry
584
	*
585
	* @since 2.0.16
586
	* @param array $values
587
	* @return int
588
	*/
589
	private static function get_is_draft_value( $values ) {
590
		return ( ( isset( $values['frm_saving_draft'] ) && $values['frm_saving_draft'] == 1 ) || ( isset( $values['is_draft'] ) && $values['is_draft'] == 1 ) ) ? 1 : 0;
591
	}
592
593
	/**
594
	* Get the form_id value for a new entry
595
	*
596
	* @since 2.0.16
597
	* @param array $values
598
	* @return int|null
599
	*/
600
	private static function get_form_id( $values ) {
601
		return isset( $values['form_id'] ) ? (int) $values['form_id'] : null;
602
	}
603
604
	/**
605
	* Get the post_id value for a new entry
606
	*
607
	* @since 2.0.16
608
	* @param array $values
609
	* @return int
610
	*/
611
	private static function get_post_id( $values ) {
612
		return isset( $values['post_id'] ) ? (int) $values['post_id']: 0;
613
	}
614
615
	/**
616
	* Get the parent_item_id value for a new entry
617
	*
618
	* @since 2.0.16
619
	* @param array $values
620
	* @return int
621
	*/
622
	private static function get_parent_item_id( $values ) {
623
		return isset( $values['parent_item_id'] ) ? (int) $values['parent_item_id']: 0;
624
	}
625
626
	/**
627
	* Get the created_at value for a new entry
628
	*
629
	* @since 2.0.16
630
	* @param array $values
631
	* @return string
632
	*/
633
	private static function get_created_at( $values ) {
634
		return isset( $values['created_at'] ) ? $values['created_at']: current_time('mysql', 1);
635
	}
636
637
	/**
638
	* Get the updated_at value for a new entry
639
	*
640
	* @since 2.0.16
641
	* @param array $values
642
	* @return string
643
	*/
644
	private static function get_updated_at( $values ) {
645
		if ( isset( $values['updated_at'] ) ) {
646
			$updated_at = $values['updated_at'];
647
		} else {
648
			$updated_at = self::get_created_at( $values );
649
		}
650
651
		return $updated_at;
652
	}
653
654
	/**
655
	* Get the description value for a new entry
656
	*
657
	* @since 2.0.16
658
	* @param array $values
659
	* @return string
660
	*/
661
	private static function get_entry_description( $values ) {
662
		if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) {
663
			$description = maybe_serialize( $values['description'] );
664
		} else {
665
			$description = serialize( array(
666
				'browser'  => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
667
				'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
668
			) );
669
		}
670
671
		return $description;
672
	}
673
674
	/**
675
	* Get the user_id value for a new entry
676
	*
677
	* @since 2.0.16
678
	* @param array $values
679
	* @return int
680
	*/
681
	private static function get_entry_user_id( $values ) {
682
		if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
683
			$user_id = $values['frm_user_id'];
684
		} else {
685
			$current_user_id = get_current_user_id();
686
			$user_id = $current_user_id ? $current_user_id : 0;
687
		}
688
689
		return $user_id;
690
	}
691
692
	/**
693
	* Insert new entry into the database
694
	*
695
	* @since 2.0.16
696
	* @param array $new_values
697
	* @return int | boolean $entry_id
698
	*/
699
	private static function insert_entry_into_database( $new_values ) {
700
		global $wpdb;
701
702
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
703
704
		if ( ! $query_results ) {
705
			$entry_id = false;
706
		} else {
707
			$entry_id = $wpdb->insert_id;
708
		}
709
710
		return $entry_id;
711
	}
712
713
	/**
714
	* Add the new entry to global $frm_vars
715
	*
716
	* @since 2.0.16
717
	* @param int $entry_id
718
	*/
719
	private static function add_new_entry_to_frm_vars( $entry_id ) {
720
		global $frm_vars;
721
722
		if ( ! isset($frm_vars['saved_entries']) ) {
723
			$frm_vars['saved_entries'] = array();
724
		}
725
726
		$frm_vars['saved_entries'][] = (int) $entry_id;
727
	}
728
729
	/**
730
	* Add entry metas, if there are any
731
	*
732
	* @since 2.0.16
733
	* @param array $values
734
	* @param int $entry_id
735
	*/
736
	private static function maybe_add_entry_metas( $values, $entry_id ) {
737
		if ( isset($values['item_meta']) ) {
738
			FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] );
739
		}
740
	}
741
742
	/**
743
	* Trigger frm_after_create_entry hooks
744
	*
745
	* @since 2.0.16
746
	* @param int $entry_id
747
	* @param array $new_values
748
	*/
749
	private static function after_entry_created_actions( $entry_id, $values, $new_values ) {
750
		// this is a child entry
751
		$is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
752
753
		do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
754
		do_action( 'frm_after_create_entry_' . $new_values['form_id'], $entry_id , compact( 'is_child' ) );
755
	}
756
757
	/**
758
	* Actions to perform immediately after an entry is inserted in the frm_items database
759
	*
760
	* @since 2.0.16
761
	* @param array $values
762
	* @param array $new_values
763
	* @param int $entry_id
764
	*/
765
	private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) {
766
767
		self::add_new_entry_to_frm_vars( $entry_id );
768
769
		self::maybe_add_entry_metas( $values, $entry_id );
770
771
		self::clear_cache();
772
773
		self::after_entry_created_actions( $entry_id, $values, $new_values );
774
	}
775
776
	/**
777
	* Perform some actions right before updating an entry
778
	*
779
	* @since 2.0.16
780
	* @param int $id
781
	* @param array $values
782
	* @param string $update_type
783
	* @return boolean $update
784
	*/
785
	private static function before_update_entry( $id, &$values, $update_type ) {
786
		$update = true;
787
788
		global $frm_vars;
789
790
		if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
791
			$update = false;
792
		}
793
794
		if ( $update && $update_type != 'xml' ) {
795
			$values = apply_filters('frm_pre_update_entry', $values, $id);
796
		}
797
798
		return $update;
799
	}
800
801
	/**
802
	* Package the entry data for updating
803
	*
804
	* @since 2.0.16
805
	* @param int $id
806
	* @param array $values
807
	* @return array $new_values
808
	*/
809
	private static function package_entry_to_update( $id, $values ) {
810
		global $wpdb;
811
812
		$new_values = array(
813
			'name'      => self::get_new_entry_name( $values ),
814
			'form_id'   => self::get_form_id( $values ),
815
			'is_draft'  => self::get_is_draft_value( $values ),
816
			'updated_at' => current_time('mysql', 1),
817
			'updated_by' => isset($values['updated_by']) ? $values['updated_by'] : get_current_user_id(),
818
		);
819
820
		if ( isset($values['post_id']) ) {
821
			$new_values['post_id'] = (int) $values['post_id'];
822
		}
823
824
		if ( isset($values['item_key']) ) {
825
			$new_values['item_key'] = FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key', $id );
826
		}
827
828
		if ( isset($values['parent_item_id']) ) {
829
			$new_values['parent_item_id'] = (int) $values['parent_item_id'];
830
		}
831
832
		if ( isset($values['frm_user_id']) && is_numeric($values['frm_user_id']) ) {
833
			$new_values['user_id'] = $values['frm_user_id'];
834
		}
835
836
		$new_values = apply_filters('frm_update_entry', $new_values, $id);
837
838
		return $new_values;
839
	}
840
841
	/**
842
	* Perform some actions right after updating an entry
843
	*
844
	* @since 2.0.16
845
	* @param boolean|int $query_results
846
	* @param int $id
847
	* @param array $values
848
	* @param array $new_values
849
	*/
850
	private static function after_update_entry( $query_results, $id, $values, $new_values ) {
851
		if ( $query_results ) {
852
			self::clear_cache();
853
		}
854
855
		global $frm_vars;
856
		if ( ! isset( $frm_vars['saved_entries'] ) ) {
857
			$frm_vars['saved_entries'] = array();
858
		}
859
860
		$frm_vars['saved_entries'][] = (int) $id;
861
862
		if ( isset( $values['item_meta'] ) ) {
863
			FrmEntryMeta::update_entry_metas( $id, $values['item_meta'] );
864
		}
865
866
		do_action( 'frm_after_update_entry', $id, $new_values['form_id'] );
867
		do_action( 'frm_after_update_entry_' . $new_values['form_id'], $id );
868
	}
869
870
	/**
871
	* Create entry from an XML import
872
	* Certain actions aren't necessary when importing (like saving sub entries, checking for duplicates, etc.)
873
	*
874
	* @since 2.0.16
875
	* @param array $values
876
	* @return int | boolean $entry_id
877
	*/
878
	public static function create_entry_from_xml( $values ) {
879
		$entry_id = self::create_entry( $values, 'xml' );
880
881
		return $entry_id;
882
	}
883
884
	/**
885
	* Update entry from an XML import
886
	* Certain actions aren't necessary when importing (like saving sub entries and modifying other vals)
887
	*
888
	* @since 2.0.16
889
	* @param int $id
890
	* @param array $values
891
	* @return int | boolean $updated
892
	*/
893
	public static function update_entry_from_xml( $id, $values ) {
894
		$updated = self::update_entry( $id, $values, 'xml' );
895
896
		return $updated;
897
	}
898
899
    /**
900
     * @param string $key
901
     * @return int entry_id
902
     */
903
	public static function get_id_by_key( $key ) {
904
        $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
905
        return $entry_id;
906
    }
907
908
	public static function validate( $values, $exclude = false ) {
909
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate' );
910
		return FrmEntryValidate::validate( $values, $exclude );
911
	}
912
913
	public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
914
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_field' );
915
		FrmEntryValidate::validate_field( $posted_field, $errors, $values, $args );
916
	}
917
918
	public static function validate_url_field( &$errors, $field, &$value, $args ) {
919
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_url_field' );
920
		FrmEntryValidate::validate_url_field( $errors, $field, $value, $args );
921
	}
922
923
	public static function validate_email_field( &$errors, $field, $value, $args ) {
924
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_email_field' );
925
		FrmEntryValidate::validate_email_field( $errors, $field, $value, $args );
926
	}
927
928
	public static function validate_recaptcha( &$errors, $field, $args ) {
929
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_recaptcha' );
930
		FrmEntryValidate::validate_recaptcha( $errors, $field, $args );
931
	}
932
933
	public static function spam_check( $exclude, $values, &$errors ) {
934
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::spam_check' );
935
		FrmEntryValidate::spam_check( $exclude, $values, $errors );
936
	}
937
938
	public static function blacklist_check( $values ) {
939
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::blacklist_check' );
940
		return FrmEntryValidate::blacklist_check( $values );
941
	}
942
943
	public static function akismet( $values ) {
944
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::akismet' );
945
		return FrmEntryValidate::akismet( $values );
946
	}
947
}
948