Completed
Push — master ( 0841f7...c277a4 )
by Stephanie
03:30
created

FrmEntry::getOne()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 6
nop 2
dl 0
loc 25
rs 8.5806
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'] = $new_values['updated_by'] = (int) $values->user_id;
138
        $new_values['form_id'] = $values->form_id ? (int) $values->form_id: null;
139
        $new_values['created_at'] = $new_values['updated_at'] = current_time('mysql', 1);
140
141
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
142
        if ( ! $query_results ) {
143
            return false;
144
        }
145
146
        $entry_id = $wpdb->insert_id;
147
148
        global $frm_vars;
149
        if ( ! isset($frm_vars['saved_entries']) ) {
150
            $frm_vars['saved_entries'] = array();
151
        }
152
        $frm_vars['saved_entries'][] = (int) $entry_id;
153
154
        FrmEntryMeta::duplicate_entry_metas($id, $entry_id);
155
		self::clear_cache();
156
157
		do_action( 'frm_after_duplicate_entry', $entry_id, $new_values['form_id'], array( 'old_id' => $id ) );
158
        return $entry_id;
159
    }
160
161
	/**
162
	* Update an entry (not via XML)
163
	*
164
	* @param int $id
165
	* @param array $values
166
	* @return boolean|int $update_results
167
	*/
168
	public static function update( $id, $values ) {
169
		$update_results = self::update_entry( $id, $values, 'standard' );
170
171
		return $update_results;
172
	}
173
174
	/**
175
	* Update an entry with some differences depending on the update type
176
	*
177
	* @since 2.0.16
178
	*
179
	* @param int $id
180
	* @param array $values
181
	* @return boolean|int $query_results
182
	*/
183
	private static function update_entry( $id, $values, $update_type ) {
184
		global $wpdb;
185
186
		$update = self::before_update_entry( $id, $values, $update_type );
187
		if ( ! $update ) {
188
			return false;
189
		}
190
191
		$new_values = self::package_entry_to_update( $id, $values );
192
193
		$query_results = $wpdb->update( $wpdb->prefix . 'frm_items', $new_values, compact('id') );
194
195
		self::after_update_entry( $query_results, $id, $values, $new_values );
196
197
		return $query_results;
198
	}
199
200
	public static function &destroy( $id ) {
201
        global $wpdb;
202
        $id = (int) $id;
203
204
		$entry = self::getOne( $id );
205
        if ( ! $entry ) {
206
            $result = false;
207
            return $result;
208
        }
209
210
        do_action('frm_before_destroy_entry', $id, $entry);
211
212
		$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas WHERE item_id=%d', $id ) );
213
		$result = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_items WHERE id=%d', $id ) );
214
215
		self::clear_cache();
216
217
        return $result;
218
    }
219
220
	public static function &update_form( $id, $value, $form_id ) {
221
        global $wpdb;
222
        $form_id = isset($value) ? $form_id : null;
223
		$result = $wpdb->update( $wpdb->prefix . 'frm_items', array( 'form_id' => $form_id ), array( 'id' => $id ) );
224
		if ( $result ) {
225
			self::clear_cache();
226
		}
227
        return $result;
228
    }
229
230
	/**
231
	 * Clear entry caching
232
	 * Called when an entry is changed
233
	 *
234
	 * @since 2.0.5
235
	 */
236
	public static function clear_cache() {
237
		FrmAppHelper::cache_delete_group( 'frm_entry' );
238
		FrmAppHelper::cache_delete_group( 'frm_item' );
239
		FrmAppHelper::cache_delete_group( 'frm_entry_meta' );
240
		FrmAppHelper::cache_delete_group( 'frm_item_meta' );
241
	}
242
243
	/**
244
	 * After switching to the wp_loaded hook for processing entries,
245
	 * we can no longer use 'name', but check it as a fallback
246
	 * @since 2.0.11
247
	 */
248
	public static function get_new_entry_name( $values, $default = '' ) {
249
		return isset( $values['item_name'] ) ? $values['item_name'] : ( isset( $values['name'] ) ? $values['name'] : $default );
250
	}
251
252
	/**
253
	 * If $entry is numeric, get the entry object
254
	 * @param int|object $entry by reference
255
	 * @since 2.0.9
256
	 */
257
	public static function maybe_get_entry( &$entry ) {
258
		if ( $entry && is_numeric( $entry ) ) {
259
			$entry = self::getOne( $entry );
260
		}
261
	}
262
263
	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...
264
        global $wpdb;
265
266
        $query = "SELECT it.*, fr.name as form_name, fr.form_key as form_key FROM {$wpdb->prefix}frm_items it
267
                  LEFT OUTER JOIN {$wpdb->prefix}frm_forms fr ON it.form_id=fr.id WHERE ";
268
269
        $query .= is_numeric($id) ? 'it.id=%d' : 'it.item_key=%s';
270
        $query_args = array( $id );
271
        $query = $wpdb->prepare( $query, $query_args );
272
273
        if ( ! $meta ) {
274
			$entry = FrmAppHelper::check_cache( $id . '_nometa', 'frm_entry', $query, 'get_row' );
275
            return stripslashes_deep($entry);
276
        }
277
278
        $entry = FrmAppHelper::check_cache( $id, 'frm_entry' );
279
        if ( $entry !== false ) {
280
            return stripslashes_deep($entry);
281
        }
282
283
        $entry = $wpdb->get_row( $query );
284
        $entry = self::get_meta($entry);
285
286
        return stripslashes_deep($entry);
287
    }
288
289
	public static function get_meta( $entry ) {
290
        if ( ! $entry ) {
291
            return $entry;
292
        }
293
294
        global $wpdb;
295
		$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' );
296
297
        $entry->metas = array();
298
299
		$include_key = apply_filters( 'frm_include_meta_keys', false, array( 'form_id' => $entry->form_id ) );
300
        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...
301
            if ( $meta_val->item_id == $entry->id ) {
302
				$entry->metas[ $meta_val->field_id ] = maybe_unserialize( $meta_val->meta_value );
303
				if ( $include_key ) {
304
					$entry->metas[ $meta_val->field_key ] = $entry->metas[ $meta_val->field_id ];
305
				}
306
                 continue;
307
            }
308
309
            // include sub entries in an array
310
			if ( ! isset( $entry_metas[ $meta_val->field_id ] ) ) {
311
				$entry->metas[ $meta_val->field_id ] = array();
312
            }
313
314
			$entry->metas[ $meta_val->field_id ][] = maybe_unserialize( $meta_val->meta_value );
315
316
            unset($meta_val);
317
        }
318
        unset($metas);
319
320
		FrmAppHelper::set_cache( $entry->id, $entry, 'frm_entry' );
321
322
        return $entry;
323
    }
324
325
    /**
326
     * @param string $id
327
     */
328
	public static function &exists( $id ) {
329
        global $wpdb;
330
331
        if ( FrmAppHelper::check_cache( $id, 'frm_entry' ) ) {
332
            $exists = true;
333
            return $exists;
334
        }
335
336
        if ( is_numeric($id) ) {
337
            $where = array( 'id' => $id );
338
        } else {
339
            $where = array( 'item_key' => $id );
340
        }
341
		$id = FrmDb::get_var( $wpdb->prefix . 'frm_items', $where );
342
343
        $exists = ($id && $id > 0) ? true : false;
344
        return $exists;
345
    }
346
347
    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...
348
		global $wpdb;
349
350
        $limit = FrmAppHelper::esc_limit($limit);
351
352
        $cache_key = maybe_serialize($where) . $order_by . $limit . $inc_form;
353
        $entries = wp_cache_get($cache_key, 'frm_entry');
354
355
        if ( false === $entries ) {
356
            $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';
357
			$table = $wpdb->prefix . 'frm_items it ';
358
359
            if ( $inc_form ) {
360
                $fields = 'it.*, fr.name as form_name,fr.form_key as form_key';
361
                $table .= 'LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id ';
362
            }
363
364
            if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) {
365
    		    // sort by a requested field
366
                $field_id = (int) $order_matches[1];
367
				$fields .= ', (SELECT meta_value FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id = ' . $field_id . ' AND item_id = it.id) as meta_' . $field_id;
368
				unset( $order_matches, $field_id );
369
		    }
370
371
			// prepare the query
372
			$query = 'SELECT ' . $fields . ' FROM ' . $table . FrmAppHelper::prepend_and_or_where(' WHERE ', $where) . $order_by . $limit;
373
374
            $entries = $wpdb->get_results($query, OBJECT_K);
375
            unset($query);
376
377
			FrmAppHelper::set_cache( $cache_key, $entries, 'frm_entry' );
378
        }
379
380
        if ( ! $meta || ! $entries ) {
381
            return stripslashes_deep($entries);
382
        }
383
        unset($meta);
384
385
        if ( ! is_array( $where ) && preg_match('/^it\.form_id=\d+$/', $where) ) {
386
			$where = array( 'it.form_id' => substr( $where, 11 ) );
387
        }
388
389
        $meta_where = array( 'field_id !' => 0 );
390
        if ( $limit == '' && is_array($where) && count($where) == 1 && isset($where['it.form_id']) ) {
391
            $meta_where['fi.form_id'] = $where['it.form_id'];
392
        } else {
393
            $meta_where['item_id'] = array_keys( $entries );
394
        }
395
396
        $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' );
397
398
        unset( $meta_where );
399
400
        if ( ! $metas ) {
401
            return stripslashes_deep($entries);
402
        }
403
404
        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...
405
            if ( ! isset( $entries[ $meta_val->item_id ] ) ) {
406
                continue;
407
            }
408
409
            if ( ! isset( $entries[ $meta_val->item_id ]->metas ) ) {
410
				$entries[ $meta_val->item_id ]->metas = array();
411
            }
412
413
			$entries[ $meta_val->item_id ]->metas[ $meta_val->field_id ] = maybe_unserialize( $meta_val->meta_value );
414
415
            unset($m_key, $meta_val);
416
        }
417
418
		if ( ! FrmAppHelper::prevent_caching() ) {
419
			foreach ( $entries as $entry ) {
420
				FrmAppHelper::set_cache( $entry->id, $entry, 'frm_entry' );
421
				unset( $entry );
422
			}
423
		}
424
425
        return stripslashes_deep($entries);
426
    }
427
428
    // Pagination Methods
429
    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...
430
        global $wpdb;
431
		$table_join = $wpdb->prefix . 'frm_items it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id';
432
433
        if ( is_numeric($where) ) {
434
            $table_join = 'frm_items';
435
            $where = array( 'form_id' => $where );
436
        }
437
438
        if ( is_array( $where ) ) {
439
            $count = FrmDb::get_count( $table_join, $where );
440
        } else {
441
			$cache_key = 'count_' . maybe_serialize( $where );
442
			$query = 'SELECT COUNT(*) FROM ' . $table_join . FrmAppHelper::prepend_and_or_where( ' WHERE ', $where );
443
			$count = FrmAppHelper::check_cache( $cache_key, 'frm_entry', $query, 'get_var' );
444
        }
445
446
        return $count;
447
    }
448
449
    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...
450
		$p_size = (int) $p_size;
451
		$count = 1;
452
		if ( $p_size ) {
453
			if ( ! is_numeric( $where ) ) {
454
				$where = self::getRecordCount( $where );
455
			}
456
			$count = ceil( (int) $where / $p_size );
457
		}
458
459
		return $count;
460
    }
461
462
	/**
463
	* Prepare the data before inserting it into the database
464
	*
465
	* @since 2.0.16
466
	* @param array $values
467
	* @param string $type
468
	* @return array $new_values
469
	*/
470
	private static function before_insert_entry_in_database( &$values, $type ) {
471
472
		self::sanitize_entry_post( $values );
473
474
		if ( $type != 'xml' ) {
475
			$values = apply_filters('frm_pre_create_entry', $values);
476
		}
477
478
		$new_values = self::package_entry_data( $values );
479
480
		return $new_values;
481
	}
482
483
	/**
484
	* Create an entry and perform after create actions
485
	*
486
	* @since 2.0.16
487
	* @param array $values
488
	* @param array $new_values
489
	* @return boolean|int $entry_id
490
	*/
491
	private static function continue_to_create_entry( $values, $new_values ) {
492
		$entry_id = self::insert_entry_into_database( $new_values );
493
		if ( ! $entry_id ) {
494
			return false;
495
		}
496
497
		self::after_insert_entry_in_database( $values, $new_values, $entry_id );
498
499
		return $entry_id;
500
	}
501
502
    /**
503
     * Sanitize the POST values before we use them
504
     *
505
     * @since 2.0
506
     * @param array $values The POST values by reference
507
     */
508
    public static function sanitize_entry_post( &$values ) {
509
        $sanitize_method = array(
510
            'form_id'       => 'absint',
511
            'frm_action'    => 'sanitize_title',
512
            'form_key'      => 'sanitize_title',
513
            'item_key'      => 'sanitize_title',
514
            'item_name'     => 'sanitize_text_field',
515
            'frm_saving_draft' => 'absint',
516
            'is_draft'      => 'absint',
517
            'post_id'       => 'absint',
518
            'parent_item_id' => 'absint',
519
            'created_at'    => 'sanitize_text_field',
520
            'updated_at'    => 'sanitize_text_field',
521
        );
522
523
        FrmAppHelper::sanitize_request( $sanitize_method, $values );
524
    }
525
526
	/**
527
	* Prepare the new values for inserting into the database
528
	*
529
	* @since 2.0.16
530
	* @param array $values
531
	* @return array $new_values
532
	*/
533
	private static function package_entry_data( &$values ) {
534
		global $wpdb;
535
536
		if ( ! isset( $values['item_key'] ) ) {
537
			$values['item_key'] = '';
538
		}
539
540
		$item_name = self::get_new_entry_name( $values, $values['item_key'] );
541
		$new_values = array(
542
			'item_key'  => FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key' ),
543
			'name'      => FrmAppHelper::truncate( $item_name, 255, 1, '' ),
544
			'ip'        => FrmAppHelper::get_ip_address(),
545
			'is_draft'  => self::get_is_draft_value( $values ),
546
			'form_id'   => self::get_form_id( $values ),
547
			'post_id'   => self::get_post_id( $values ),
548
			'parent_item_id' => self::get_parent_item_id( $values ),
549
			'created_at' => self::get_created_at( $values ),
550
			'updated_at' => self::get_updated_at( $values ),
551
			'description' => self::get_entry_description( $values ),
552
			'user_id' => self::get_entry_user_id( $values ),
553
		);
554
555
		if ( is_array($new_values['name']) ) {
556
			$new_values['name'] = reset($new_values['name']);
557
		}
558
559
		$new_values['updated_by'] = isset($values['updated_by']) ? $values['updated_by'] : $new_values['user_id'];
560
561
		return $new_values;
562
	}
563
564
	/**
565
	* Get the is_draft value for a new entry
566
	*
567
	* @since 2.0.16
568
	* @param array $values
569
	* @return int
570
	*/
571
	private static function get_is_draft_value( $values ) {
572
		return ( ( isset( $values['frm_saving_draft'] ) && $values['frm_saving_draft'] == 1 ) ||  ( isset( $values['is_draft'] ) && $values['is_draft'] == 1 ) ) ? 1 : 0;
573
	}
574
575
	/**
576
	* Get the form_id value for a new entry
577
	*
578
	* @since 2.0.16
579
	* @param array $values
580
	* @return int|null
581
	*/
582
	private static function get_form_id( $values ) {
583
		return isset( $values['form_id'] ) ? (int) $values['form_id'] : null;
584
	}
585
586
	/**
587
	* Get the post_id value for a new entry
588
	*
589
	* @since 2.0.16
590
	* @param array $values
591
	* @return int
592
	*/
593
	private static function get_post_id( $values ) {
594
		return isset( $values['post_id'] ) ? (int) $values['post_id']: 0;
595
	}
596
597
	/**
598
	* Get the parent_item_id value for a new entry
599
	*
600
	* @since 2.0.16
601
	* @param array $values
602
	* @return int
603
	*/
604
	private static function get_parent_item_id( $values ) {
605
		return isset( $values['parent_item_id'] ) ? (int) $values['parent_item_id']: 0;
606
	}
607
608
	/**
609
	* Get the created_at value for a new entry
610
	*
611
	* @since 2.0.16
612
	* @param array $values
613
	* @return string
614
	*/
615
	private static function get_created_at( $values ) {
616
		return isset( $values['created_at'] ) ? $values['created_at']: current_time('mysql', 1);
617
	}
618
619
	/**
620
	* Get the updated_at value for a new entry
621
	*
622
	* @since 2.0.16
623
	* @param array $values
624
	* @return string
625
	*/
626
	private static function get_updated_at( $values ) {
627
		if ( isset( $values['updated_at'] ) ) {
628
			$updated_at = $values['updated_at'];
629
		} else {
630
			$updated_at = self::get_created_at( $values );
631
		}
632
633
		return $updated_at;
634
	}
635
636
	/**
637
	* Get the description value for a new entry
638
	*
639
	* @since 2.0.16
640
	* @param array $values
641
	* @return string
642
	*/
643
	private static function get_entry_description( $values ) {
644
		if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) {
645
			$description = maybe_serialize( $values['description'] );
646
		} else {
647
			$description = serialize( array(
648
				'browser'  => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
649
				'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
650
			) );
651
		}
652
653
		return $description;
654
	}
655
656
	/**
657
	* Get the user_id value for a new entry
658
	*
659
	* @since 2.0.16
660
	* @param array $values
661
	* @return int
662
	*/
663
	private static function get_entry_user_id( $values ) {
664
		if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
665
			$user_id = $values['frm_user_id'];
666
		} else {
667
			$current_user_id = get_current_user_id();
668
			$user_id = $current_user_id ? $current_user_id : 0;
669
		}
670
671
		return $user_id;
672
	}
673
674
	/**
675
	* Insert new entry into the database
676
	*
677
	* @since 2.0.16
678
	* @param array $new_values
679
	* @return int | boolean $entry_id
680
	*/
681
	private static function insert_entry_into_database( $new_values ) {
682
		global $wpdb;
683
684
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
685
686
		if ( ! $query_results ) {
687
			$entry_id = false;
688
		} else {
689
			$entry_id = $wpdb->insert_id;
690
		}
691
692
		return $entry_id;
693
	}
694
695
	/**
696
	* Add the new entry to global $frm_vars
697
	*
698
	* @since 2.0.16
699
	* @param int $entry_id
700
	*/
701
	private static function add_new_entry_to_frm_vars( $entry_id ) {
702
		global $frm_vars;
703
704
		if ( ! isset($frm_vars['saved_entries']) ) {
705
			$frm_vars['saved_entries'] = array();
706
		}
707
708
		$frm_vars['saved_entries'][] = (int) $entry_id;
709
	}
710
711
	/**
712
	* Add entry metas, if there are any
713
	*
714
	* @since 2.0.16
715
	* @param array $values
716
	* @param int $entry_id
717
	*/
718
	private static function maybe_add_entry_metas( $values, $entry_id ) {
719
		if ( isset($values['item_meta']) ) {
720
			FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] );
721
		}
722
	}
723
724
	/**
725
	* Trigger frm_after_create_entry hooks
726
	*
727
	* @since 2.0.16
728
	* @param int $entry_id
729
	* @param array $new_values
730
	*/
731
	private static function after_entry_created_actions( $entry_id, $values, $new_values ) {
732
		// this is a child entry
733
		$is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
734
735
		do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
736
		do_action( 'frm_after_create_entry_' . $new_values['form_id'], $entry_id , compact( 'is_child' ) );
737
	}
738
739
	/**
740
	* Actions to perform immediately after an entry is inserted in the frm_items database
741
	*
742
	* @since 2.0.16
743
	* @param array $values
744
	* @param array $new_values
745
	* @param int $entry_id
746
	*/
747
	private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) {
748
749
		self::add_new_entry_to_frm_vars( $entry_id );
750
751
		self::maybe_add_entry_metas( $values, $entry_id );
752
753
		self::clear_cache();
754
755
		self::after_entry_created_actions( $entry_id, $values, $new_values );
756
	}
757
758
	/**
759
	* Perform some actions right before updating an entry
760
	*
761
	* @since 2.0.16
762
	* @param int $id
763
	* @param array $values
764
	* @param string $update_type
765
	* @return boolean $update
766
	*/
767
	private static function before_update_entry( $id, &$values, $update_type ) {
768
		$update = true;
769
770
		global $frm_vars;
771
772
		if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
773
			$update = false;
774
		}
775
776
		if ( $update && $update_type != 'xml' ) {
777
			$values = apply_filters('frm_pre_update_entry', $values, $id);
778
		}
779
780
		return $update;
781
	}
782
783
	/**
784
	* Package the entry data for updating
785
	*
786
	* @since 2.0.16
787
	* @param int $id
788
	* @param array $values
789
	* @return array $new_values
790
	*/
791
	private static function package_entry_to_update( $id, $values ) {
792
		global $wpdb;
793
794
		$new_values = array(
795
			'name'      => self::get_new_entry_name( $values ),
796
			'form_id'   => self::get_form_id( $values ),
797
			'is_draft'  => self::get_is_draft_value( $values ),
798
			'updated_at' => current_time('mysql', 1),
799
			'updated_by' => isset($values['updated_by']) ? $values['updated_by'] : get_current_user_id(),
800
		);
801
802
		if ( isset($values['post_id']) ) {
803
			$new_values['post_id'] = (int) $values['post_id'];
804
		}
805
806
		if ( isset($values['item_key']) ) {
807
			$new_values['item_key'] = FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key', $id );
808
		}
809
810
		if ( isset($values['parent_item_id']) ) {
811
			$new_values['parent_item_id'] = (int) $values['parent_item_id'];
812
		}
813
814
		if ( isset($values['frm_user_id']) && is_numeric($values['frm_user_id']) ) {
815
			$new_values['user_id'] = $values['frm_user_id'];
816
		}
817
818
		$new_values = apply_filters('frm_update_entry', $new_values, $id);
819
820
		return $new_values;
821
	}
822
823
	/**
824
	* Perform some actions right after updating an entry
825
	*
826
	* @since 2.0.16
827
	* @param boolean|int $query_results
828
	* @param int $id
829
	* @param array $values
830
	* @param array $new_values
831
	*/
832
	private static function after_update_entry( $query_results, $id, $values, $new_values ) {
833
		if ( $query_results ) {
834
			self::clear_cache();
835
		}
836
837
		global $frm_vars;
838
		if ( ! isset( $frm_vars['saved_entries'] ) ) {
839
			$frm_vars['saved_entries'] = array();
840
		}
841
842
		$frm_vars['saved_entries'][] = (int) $id;
843
844
		if ( isset( $values['item_meta'] ) ) {
845
			FrmEntryMeta::update_entry_metas( $id, $values['item_meta'] );
846
		}
847
848
		do_action( 'frm_after_update_entry', $id, $new_values['form_id'] );
849
		do_action( 'frm_after_update_entry_' . $new_values['form_id'], $id );
850
	}
851
852
	/**
853
	* Create entry from an XML import
854
	* Certain actions aren't necessary when importing (like saving sub entries, checking for duplicates, etc.)
855
	*
856
	* @since 2.0.16
857
	* @param array $values
858
	* @return int | boolean $entry_id
859
	*/
860
	public static function create_entry_from_xml( $values ) {
861
		$entry_id = self::create_entry( $values, 'xml' );
862
863
		return $entry_id;
864
	}
865
866
	/**
867
	* Update entry from an XML import
868
	* Certain actions aren't necessary when importing (like saving sub entries and modifying other vals)
869
	*
870
	* @since 2.0.16
871
	* @param int $id
872
	* @param array $values
873
	* @return int | boolean $updated
874
	*/
875
	public static function update_entry_from_xml( $id, $values ) {
876
		$updated = self::update_entry( $id, $values, 'xml' );
877
878
		return $updated;
879
	}
880
881
    /**
882
     * @param string $key
883
     * @return int entry_id
884
     */
885
	public static function get_id_by_key( $key ) {
886
        $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
887
        return $entry_id;
888
    }
889
890
	public static function validate( $values, $exclude = false ) {
891
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate' );
892
		return FrmEntryValidate::validate( $values, $exclude );
893
	}
894
895
	public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
896
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_field' );
897
		FrmEntryValidate::validate_field( $posted_field, $errors, $values, $args );
898
	}
899
900
	public static function validate_url_field( &$errors, $field, &$value, $args ) {
901
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_url_field' );
902
		FrmEntryValidate::validate_url_field( $errors, $field, $value, $args );
903
	}
904
905
	public static function validate_email_field( &$errors, $field, $value, $args ) {
906
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_email_field' );
907
		FrmEntryValidate::validate_email_field( $errors, $field, $value, $args );
908
	}
909
910
	public static function validate_recaptcha( &$errors, $field, $args ) {
911
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_recaptcha' );
912
		FrmEntryValidate::validate_recaptcha( $errors, $field, $args );
913
	}
914
915
	public static function spam_check( $exclude, $values, &$errors ) {
916
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::spam_check' );
917
		FrmEntryValidate::spam_check( $exclude, $values, $errors );
918
	}
919
920
	public static function blacklist_check( $values ) {
921
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::blacklist_check' );
922
		return FrmEntryValidate::blacklist_check( $values );
923
	}
924
925
	public static function akismet( $values ) {
926
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::akismet' );
927
		return FrmEntryValidate::akismet( $values );
928
	}
929
}
930