Completed
Push — master ( a7a5ee...d06372 )
by Stephanie
03:31
created

FrmEntry::get_entry_description()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 1
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'   => (int) self::get_entry_value( $values, 'form_id', null ),
549
			'post_id'   => (int) self::get_entry_value( $values, 'post_id', 0 ),
550
			'parent_item_id' => (int) self::get_entry_value( $values, 'parent_item_id', 0 ),
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
	private static function get_entry_value( $values, $name, $default ) {
567
		return isset( $values[ $name ] ) ? $values[ $name ] : $default;
568
	}
569
570
	/**
571
	 * Get the ip for a new entry.
572
	 * Allow the import to override the value.
573
	 *
574
	 * @since 2.03.10
575
	 * @param array $values
576
	 * @return string
577
	 */
578
	private static function get_ip( $values ) {
579
		$ip = FrmAppHelper::get_ip_address();
580
		if ( defined('WP_IMPORTING') && WP_IMPORTING ) {
581
			$ip = self::get_entry_value( $values, 'ip', $ip );
582
		}
583
		return $ip;
584
	}
585
586
	/**
587
	* Get the is_draft value for a new entry
588
	*
589
	* @since 2.0.16
590
	* @param array $values
591
	* @return int
592
	*/
593
	private static function get_is_draft_value( $values ) {
594
		return ( ( isset( $values['frm_saving_draft'] ) && $values['frm_saving_draft'] == 1 ) || ( isset( $values['is_draft'] ) && $values['is_draft'] == 1 ) ) ? 1 : 0;
595
	}
596
597
	/**
598
	* Get the created_at value for a new entry
599
	*
600
	* @since 2.0.16
601
	* @param array $values
602
	* @return string
603
	*/
604
	private static function get_created_at( $values ) {
605
		return self::get_entry_value( $values, 'created_at', current_time( 'mysql', 1 ) );
606
	}
607
608
	/**
609
	* Get the updated_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_updated_at( $values ) {
616
		if ( isset( $values['updated_at'] ) ) {
617
			$updated_at = $values['updated_at'];
618
		} else {
619
			$updated_at = self::get_created_at( $values );
620
		}
621
622
		return $updated_at;
623
	}
624
625
	/**
626
	* Get the description value for a new entry
627
	*
628
	* @since 2.0.16
629
	* @param array $values
630
	* @return string
631
	*/
632
	private static function get_entry_description( $values ) {
633
		if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) {
634
			$description = maybe_serialize( $values['description'] );
635
		} else {
636
			$description = serialize( array(
637
				'browser'  => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
638
				'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
639
			) );
640
		}
641
642
		return $description;
643
	}
644
645
	/**
646
	* Get the user_id value for a new entry
647
	*
648
	* @since 2.0.16
649
	* @param array $values
650
	* @return int
651
	*/
652
	private static function get_entry_user_id( $values ) {
653
		if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
654
			$user_id = $values['frm_user_id'];
655
		} else {
656
			$current_user_id = get_current_user_id();
657
			$user_id = $current_user_id ? $current_user_id : 0;
658
		}
659
660
		return $user_id;
661
	}
662
663
	/**
664
	* Insert new entry into the database
665
	*
666
	* @since 2.0.16
667
	* @param array $new_values
668
	* @return int | boolean $entry_id
669
	*/
670
	private static function insert_entry_into_database( $new_values ) {
671
		global $wpdb;
672
673
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
674
675
		if ( ! $query_results ) {
676
			$entry_id = false;
677
		} else {
678
			$entry_id = $wpdb->insert_id;
679
		}
680
681
		return $entry_id;
682
	}
683
684
	/**
685
	* Add the new entry to global $frm_vars
686
	*
687
	* @since 2.0.16
688
	* @param int $entry_id
689
	*/
690
	private static function add_new_entry_to_frm_vars( $entry_id ) {
691
		global $frm_vars;
692
693
		if ( ! isset($frm_vars['saved_entries']) ) {
694
			$frm_vars['saved_entries'] = array();
695
		}
696
697
		$frm_vars['saved_entries'][] = (int) $entry_id;
698
	}
699
700
	/**
701
	* Add entry metas, if there are any
702
	*
703
	* @since 2.0.16
704
	* @param array $values
705
	* @param int $entry_id
706
	*/
707
	private static function maybe_add_entry_metas( $values, $entry_id ) {
708
		if ( isset($values['item_meta']) ) {
709
			FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] );
710
		}
711
	}
712
713
	/**
714
	* Trigger frm_after_create_entry hooks
715
	*
716
	* @since 2.0.16
717
	* @param int $entry_id
718
	* @param array $new_values
719
	*/
720
	private static function after_entry_created_actions( $entry_id, $values, $new_values ) {
721
		// this is a child entry
722
		$is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
723
724
		do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
725
		do_action( 'frm_after_create_entry_' . $new_values['form_id'], $entry_id , compact( 'is_child' ) );
726
	}
727
728
	/**
729
	* Actions to perform immediately after an entry is inserted in the frm_items database
730
	*
731
	* @since 2.0.16
732
	* @param array $values
733
	* @param array $new_values
734
	* @param int $entry_id
735
	*/
736
	private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) {
737
738
		self::add_new_entry_to_frm_vars( $entry_id );
739
740
		self::maybe_add_entry_metas( $values, $entry_id );
741
742
		self::clear_cache();
743
744
		self::after_entry_created_actions( $entry_id, $values, $new_values );
745
	}
746
747
	/**
748
	* Perform some actions right before updating an entry
749
	*
750
	* @since 2.0.16
751
	* @param int $id
752
	* @param array $values
753
	* @param string $update_type
754
	* @return boolean $update
755
	*/
756
	private static function before_update_entry( $id, &$values, $update_type ) {
757
		$update = true;
758
759
		global $frm_vars;
760
761
		if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
762
			$update = false;
763
		}
764
765
		if ( $update && $update_type != 'xml' ) {
766
			$values = apply_filters('frm_pre_update_entry', $values, $id);
767
		}
768
769
		return $update;
770
	}
771
772
	/**
773
	* Package the entry data for updating
774
	*
775
	* @since 2.0.16
776
	* @param int $id
777
	* @param array $values
778
	* @return array $new_values
779
	*/
780
	private static function package_entry_to_update( $id, $values ) {
781
		global $wpdb;
782
783
		$new_values = array(
784
			'name'      => self::get_new_entry_name( $values ),
785
			'form_id'   => (int) self::get_entry_value( $values, 'form_id', null ),
786
			'is_draft'  => self::get_is_draft_value( $values ),
787
			'updated_at' => current_time('mysql', 1),
788
			'updated_by' => isset($values['updated_by']) ? $values['updated_by'] : get_current_user_id(),
789
		);
790
791
		if ( isset($values['post_id']) ) {
792
			$new_values['post_id'] = (int) $values['post_id'];
793
		}
794
795
		if ( isset($values['item_key']) ) {
796
			$new_values['item_key'] = FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key', $id );
797
		}
798
799
		if ( isset($values['parent_item_id']) ) {
800
			$new_values['parent_item_id'] = (int) $values['parent_item_id'];
801
		}
802
803
		if ( isset($values['frm_user_id']) && is_numeric($values['frm_user_id']) ) {
804
			$new_values['user_id'] = $values['frm_user_id'];
805
		}
806
807
		$new_values = apply_filters('frm_update_entry', $new_values, $id);
808
809
		return $new_values;
810
	}
811
812
	/**
813
	* Perform some actions right after updating an entry
814
	*
815
	* @since 2.0.16
816
	* @param boolean|int $query_results
817
	* @param int $id
818
	* @param array $values
819
	* @param array $new_values
820
	*/
821
	private static function after_update_entry( $query_results, $id, $values, $new_values ) {
822
		if ( $query_results ) {
823
			self::clear_cache();
824
		}
825
826
		global $frm_vars;
827
		if ( ! isset( $frm_vars['saved_entries'] ) ) {
828
			$frm_vars['saved_entries'] = array();
829
		}
830
831
		$frm_vars['saved_entries'][] = (int) $id;
832
833
		if ( isset( $values['item_meta'] ) ) {
834
			FrmEntryMeta::update_entry_metas( $id, $values['item_meta'] );
835
		}
836
837
		do_action( 'frm_after_update_entry', $id, $new_values['form_id'] );
838
		do_action( 'frm_after_update_entry_' . $new_values['form_id'], $id );
839
	}
840
841
	/**
842
	* Create entry from an XML import
843
	* Certain actions aren't necessary when importing (like saving sub entries, checking for duplicates, etc.)
844
	*
845
	* @since 2.0.16
846
	* @param array $values
847
	* @return int | boolean $entry_id
848
	*/
849
	public static function create_entry_from_xml( $values ) {
850
		$entry_id = self::create_entry( $values, 'xml' );
851
852
		return $entry_id;
853
	}
854
855
	/**
856
	* Update entry from an XML import
857
	* Certain actions aren't necessary when importing (like saving sub entries and modifying other vals)
858
	*
859
	* @since 2.0.16
860
	* @param int $id
861
	* @param array $values
862
	* @return int | boolean $updated
863
	*/
864
	public static function update_entry_from_xml( $id, $values ) {
865
		$updated = self::update_entry( $id, $values, 'xml' );
866
867
		return $updated;
868
	}
869
870
    /**
871
     * @param string $key
872
     * @return int entry_id
873
     */
874
	public static function get_id_by_key( $key ) {
875
        $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
876
        return $entry_id;
877
    }
878
879
	public static function validate( $values, $exclude = false ) {
880
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate' );
881
		return FrmEntryValidate::validate( $values, $exclude );
882
	}
883
884
	public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
885
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_field' );
886
		FrmEntryValidate::validate_field( $posted_field, $errors, $values, $args );
887
	}
888
889
	public static function validate_url_field( &$errors, $field, &$value, $args ) {
890
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_url_field' );
891
		FrmEntryValidate::validate_url_field( $errors, $field, $value, $args );
892
	}
893
894
	public static function validate_email_field( &$errors, $field, $value, $args ) {
895
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_email_field' );
896
		FrmEntryValidate::validate_email_field( $errors, $field, $value, $args );
897
	}
898
899
	public static function validate_recaptcha( &$errors, $field, $args ) {
900
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::validate_recaptcha' );
901
		FrmEntryValidate::validate_recaptcha( $errors, $field, $args );
902
	}
903
904
	public static function spam_check( $exclude, $values, &$errors ) {
905
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::spam_check' );
906
		FrmEntryValidate::spam_check( $exclude, $values, $errors );
907
	}
908
909
	public static function blacklist_check( $values ) {
910
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::blacklist_check' );
911
		return FrmEntryValidate::blacklist_check( $values );
912
	}
913
914
	public static function akismet( $values ) {
915
		_deprecated_function( __FUNCTION__, '2.0.9', 'FrmEntryValidate::akismet' );
916
		return FrmEntryValidate::akismet( $values );
917
	}
918
}
919