PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.07.01
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.07.01
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / FrmEntry.php

FrmEntry.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 4.07.01, at classes/models/FrmEntry.php

997 lines 25.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 *
13 * @return int | boolean $entry_id
14 */
15 public static function create( $values ) {
16 $entry_id = self::create_entry( $values, 'standard' );
17
18 return $entry_id;
19 }
20
21 /**
22 * Create a new entry with some differences depending on type
23 *
24 * @param array $values
25 * @param string $type
26 *
27 * @return int | boolean $entry_id
28 */
29 private static function create_entry( $values, $type ) {
30 $new_values = self::before_insert_entry_in_database( $values, $type );
31
32 // Don't check XML entries for duplicates
33 if ( $type != 'xml' && self::is_duplicate( $new_values, $values ) ) {
34 return false;
35 }
36
37 $entry_id = self::continue_to_create_entry( $values, $new_values );
38
39 return $entry_id;
40 }
41
42 /**
43 * Check for duplicate entries created in the last minute
44 *
45 * @return boolean
46 */
47 public static function is_duplicate( $new_values, $values ) {
48 $duplicate_entry_time = apply_filters( 'frm_time_to_check_duplicates', 60, $new_values );
49
50 if ( false === self::is_duplicate_check_needed( $values, $duplicate_entry_time ) ) {
51 return false;
52 }
53
54 $check_val = $new_values;
55 $check_val['created_at >'] = gmdate( 'Y-m-d H:i:s', ( strtotime( $new_values['created_at'] ) - absint( $duplicate_entry_time ) ) );
56
57 unset( $check_val['created_at'], $check_val['updated_at'] );
58 unset( $check_val['is_draft'], $check_val['id'], $check_val['item_key'] );
59
60 if ( $new_values['item_key'] == $new_values['name'] ) {
61 unset( $check_val['name'] );
62 }
63
64 global $wpdb;
65 $entry_exists = FrmDb::get_col( $wpdb->prefix . 'frm_items', $check_val, 'id', array( 'order_by' => 'created_at DESC' ) );
66
67 if ( ! $entry_exists || empty( $entry_exists ) || ! isset( $values['item_meta'] ) ) {
68 return false;
69 }
70
71 $is_duplicate = false;
72 foreach ( $entry_exists as $entry_exist ) {
73 $is_duplicate = true;
74
75 // make sure it's a duplicate
76 $metas = FrmEntryMeta::get_entry_meta_info( $entry_exist );
77 $field_metas = array();
78 foreach ( $metas as $meta ) {
79 $field_metas[ $meta->field_id ] = $meta->meta_value;
80 }
81
82 // If prev entry is empty and current entry is not, they are not duplicates
83 $filtered_vals = array_filter( $values['item_meta'] );
84 $field_metas = array_filter( $field_metas );
85 if ( empty( $field_metas ) && ! empty( $filtered_vals ) ) {
86 return false;
87 }
88
89 // compare serialized values and not arrays
90 $new_meta = array_map( 'maybe_serialize', $filtered_vals );
91
92 if ( $field_metas === $new_meta ) {
93 $is_duplicate = true;
94 break;
95 }
96
97 if ( count( $field_metas ) !== count( $new_meta ) ) {
98 // TODO: compare values saved in the post also
99 $is_duplicate = false;
100 continue;
101 }
102
103 $diff = array_diff_assoc( $field_metas, $new_meta );
104 foreach ( $diff as $field_id => $meta_value ) {
105 if ( ! empty( $meta_value ) ) {
106 $is_duplicate = false;
107 continue;
108 }
109 }
110
111 if ( $is_duplicate ) {
112 break;
113 }
114 }
115
116 return $is_duplicate;
117 }
118
119 /**
120 * Determine if an entry needs to be checked as a possible duplicate
121 *
122 * @since 2.0.23
123 *
124 * @param array $values
125 * @param int $duplicate_entry_time
126 *
127 * @return bool
128 */
129 private static function is_duplicate_check_needed( $values, $duplicate_entry_time ) {
130 // If time for checking duplicates is set to an empty value, don't check for duplicates
131 if ( empty( $duplicate_entry_time ) ) {
132 return false;
133 }
134
135 // If CSV is importing, don't check for duplicates
136 if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
137 return false;
138 }
139
140 // If repeating field entries are getting created, don't check for duplicates
141 if ( isset( $values['parent_form_id'] ) && $values['parent_form_id'] ) {
142 return false;
143 }
144
145 return true;
146 }
147
148 public static function duplicate( $id ) {
149 global $wpdb;
150
151 $values = self::getOne( $id );
152
153 $new_values = array();
154 $new_values['item_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_items', 'item_key' );
155 $new_values['name'] = $values->name;
156 $new_values['is_draft'] = $values->is_draft;
157 $new_values['user_id'] = (int) $values->user_id;
158 $new_values['updated_by'] = (int) $values->user_id;
159 $new_values['form_id'] = $values->form_id ? (int) $values->form_id : null;
160 $new_values['created_at'] = current_time( 'mysql', 1 );
161 $new_values['updated_at'] = $new_values['created_at'];
162
163 $query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
164 if ( ! $query_results ) {
165 return false;
166 }
167
168 $entry_id = $wpdb->insert_id;
169
170 global $frm_vars;
171 if ( ! isset( $frm_vars['saved_entries'] ) ) {
172 $frm_vars['saved_entries'] = array();
173 }
174 $frm_vars['saved_entries'][] = (int) $entry_id;
175
176 FrmEntryMeta::duplicate_entry_metas( $id, $entry_id );
177 self::clear_cache();
178
179 do_action( 'frm_after_duplicate_entry', $entry_id, $new_values['form_id'], array( 'old_id' => $id ) );
180
181 return $entry_id;
182 }
183
184 /**
185 * Update an entry (not via XML)
186 *
187 * @param int $id
188 * @param array $values
189 *
190 * @return boolean|int $update_results
191 */
192 public static function update( $id, $values ) {
193 $update_results = self::update_entry( $id, $values, 'standard' );
194
195 return $update_results;
196 }
197
198 /**
199 * Update an entry with some differences depending on the update type
200 *
201 * @since 2.0.16
202 *
203 * @param int $id
204 * @param array $values
205 *
206 * @return boolean|int $query_results
207 */
208 private static function update_entry( $id, $values, $update_type ) {
209 global $wpdb;
210
211 $update = self::before_update_entry( $id, $values, $update_type );
212 if ( ! $update ) {
213 return false;
214 }
215
216 $new_values = self::package_entry_to_update( $id, $values );
217
218 $query_results = $wpdb->update( $wpdb->prefix . 'frm_items', $new_values, compact( 'id' ) );
219
220 self::after_update_entry( $query_results, $id, $values, $new_values );
221
222 return $query_results;
223 }
224
225 public static function destroy( $id ) {
226 global $wpdb;
227 $id = (int) $id;
228
229 $entry = self::getOne( $id );
230 if ( ! $entry ) {
231 $result = false;
232
233 return $result;
234 }
235
236 do_action( 'frm_before_destroy_entry', $id, $entry );
237
238 $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas WHERE item_id=%d', $id ) );
239 $result = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_items WHERE id=%d', $id ) );
240
241 self::clear_cache();
242
243 return $result;
244 }
245
246 public static function update_form( $id, $value, $form_id ) {
247 global $wpdb;
248 $form_id = isset( $value ) ? $form_id : null;
249 $result = $wpdb->update( $wpdb->prefix . 'frm_items', array( 'form_id' => $form_id ), array( 'id' => $id ) );
250 if ( $result ) {
251 self::clear_cache();
252 }
253
254 return $result;
255 }
256
257 /**
258 * Clear entry caching
259 * Called when an entry is changed
260 *
261 * @since 2.0.5
262 */
263 public static function clear_cache() {
264 FrmDb::cache_delete_group( 'frm_entry' );
265 FrmDb::cache_delete_group( 'frm_item' );
266 FrmDb::cache_delete_group( 'frm_entry_meta' );
267 FrmDb::cache_delete_group( 'frm_item_meta' );
268 }
269
270 /**
271 * After switching to the wp_loaded hook for processing entries,
272 * we can no longer use 'name', but check it as a fallback
273 *
274 * @since 2.0.11
275 */
276 public static function get_new_entry_name( $values, $default = '' ) {
277 $name = isset( $values['item_name'] ) ? $values['item_name'] : ( isset( $values['name'] ) ? $values['name'] : $default );
278 if ( is_array( $name ) ) {
279 $name = reset( $name );
280 }
281
282 return $name;
283 }
284
285 /**
286 * If $entry is numeric, get the entry object
287 *
288 * @param int|object $entry by reference
289 *
290 * @since 2.0.9
291 */
292 public static function maybe_get_entry( &$entry ) {
293 if ( $entry && is_numeric( $entry ) ) {
294 $entry = self::getOne( $entry );
295 } elseif ( empty( $entry ) || 'false' === $entry ) {
296 $entry = false;
297 }
298 }
299
300 public static function getOne( $id, $meta = false ) {
301 global $wpdb;
302
303 $query = "SELECT it.*, fr.name as form_name, fr.form_key as form_key FROM {$wpdb->prefix}frm_items it
304 LEFT OUTER JOIN {$wpdb->prefix}frm_forms fr ON it.form_id=fr.id WHERE ";
305
306 $query .= is_numeric( $id ) ? 'it.id=%d' : 'it.item_key=%s';
307 $query_args = array( $id );
308 $query = $wpdb->prepare( $query, $query_args ); // WPCS: unprepared SQL ok.
309
310 if ( ! $meta ) {
311 $entry = FrmDb::check_cache( $id . '_nometa', 'frm_entry', $query, 'get_row' );
312 self::prepare_entry( $entry );
313 return $entry;
314 }
315
316 $entry = FrmDb::check_cache( $id, 'frm_entry' );
317 if ( $entry !== false ) {
318 self::prepare_entry( $entry );
319 return $entry;
320 }
321
322 $entry = $wpdb->get_row( $query ); // WPCS: unprepared SQL ok.
323 $entry = self::get_meta( $entry );
324 self::prepare_entry( $entry );
325
326 return $entry;
327 }
328
329 /**
330 * @since 4.02.03
331 *
332 * @param object $entry
333 */
334 private static function prepare_entry( &$entry ) {
335 if ( empty( $entry ) ) {
336 return;
337 }
338
339 FrmAppHelper::unserialize_or_decode( $entry->description );
340 $entry = wp_unslash( $entry ); // TODO: Remove slashes on input only, not output.
341 }
342
343 /**
344 * @since 4.02.03
345 *
346 * @param array $entries
347 */
348 private static function prepare_entries( &$entries ) {
349 foreach ( $entries as $k => $entry ) {
350 self::prepare_entry( $entry );
351 $entries[ $k ] = $entry;
352 }
353 }
354
355 public static function get_meta( $entry ) {
356 if ( ! $entry ) {
357 return $entry;
358 }
359
360 global $wpdb;
361 $metas = FrmDb::get_results(
362 $wpdb->prefix . 'frm_item_metas m LEFT JOIN ' . $wpdb->prefix . 'frm_fields f ON m.field_id=f.id',
363 array(
364 'item_id' => $entry->id,
365 'field_id !' => 0,
366 ),
367 'field_id, meta_value, field_key, item_id'
368 );
369
370 $entry->metas = array();
371
372 $include_key = apply_filters( 'frm_include_meta_keys', false, array( 'form_id' => $entry->form_id ) );
373 foreach ( $metas as $meta_val ) {
374 if ( $meta_val->item_id == $entry->id ) {
375 FrmAppHelper::unserialize_or_decode( $meta_val->meta_value );
376 $entry->metas[ $meta_val->field_id ] = $meta_val->meta_value;
377 if ( $include_key ) {
378 $entry->metas[ $meta_val->field_key ] = $entry->metas[ $meta_val->field_id ];
379 }
380 continue;
381 }
382
383 // include sub entries in an array
384 if ( ! isset( $entry_metas[ $meta_val->field_id ] ) ) {
385 $entry->metas[ $meta_val->field_id ] = array();
386 }
387
388 FrmAppHelper::unserialize_or_decode( $meta_val->meta_value );
389 $entry->metas[ $meta_val->field_id ][] = $meta_val->meta_value;
390
391 unset( $meta_val );
392 }
393 unset( $metas );
394
395 FrmDb::set_cache( $entry->id, $entry, 'frm_entry' );
396
397 return $entry;
398 }
399
400 /**
401 * @param string $id
402 */
403 public static function exists( $id ) {
404 global $wpdb;
405
406 if ( FrmDb::check_cache( $id, 'frm_entry' ) ) {
407 $exists = true;
408
409 return $exists;
410 }
411
412 if ( is_numeric( $id ) ) {
413 $where = array( 'id' => $id );
414 } else {
415 $where = array( 'item_key' => $id );
416 }
417 $id = FrmDb::get_var( $wpdb->prefix . 'frm_items', $where );
418
419 return ( $id && $id > 0 );
420 }
421
422 public static function getAll( $where, $order_by = '', $limit = '', $meta = false, $inc_form = true ) {
423 global $wpdb;
424
425 $limit = FrmDb::esc_limit( $limit );
426
427 $cache_key = FrmAppHelper::maybe_json_encode( $where ) . $order_by . $limit . $inc_form;
428 $entries = wp_cache_get( $cache_key, 'frm_entry' );
429
430 if ( false === $entries ) {
431 $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';
432 $table = $wpdb->prefix . 'frm_items it ';
433
434 if ( $inc_form ) {
435 $fields = 'it.*, fr.name as form_name,fr.form_key as form_key';
436 $table .= 'LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id ';
437 }
438
439 if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) {
440 // sort by a requested field
441 $field_id = (int) $order_matches[1];
442 $fields .= ', (SELECT meta_value FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id = ' . $field_id . ' AND item_id = it.id) as meta_' . $field_id;
443 unset( $order_matches, $field_id );
444 }
445
446 // prepare the query
447 $query = 'SELECT ' . $fields . ' FROM ' . $table . FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
448
449 $entries = $wpdb->get_results( $query, OBJECT_K ); // WPCS: unprepared SQL ok.
450 unset( $query );
451
452 FrmDb::set_cache( $cache_key, $entries, 'frm_entry' );
453 }
454
455 if ( ! $meta || ! $entries ) {
456 self::prepare_entries( $entries );
457 return $entries;
458 }
459 unset( $meta );
460
461 if ( ! is_array( $where ) && preg_match( '/^it\.form_id=\d+$/', $where ) ) {
462 $where = array( 'it.form_id' => substr( $where, 11 ) );
463 }
464
465 $meta_where = array( 'field_id !' => 0 );
466 if ( $limit == '' && is_array( $where ) && count( $where ) == 1 && isset( $where['it.form_id'] ) ) {
467 $meta_where['fi.form_id'] = $where['it.form_id'];
468 } else {
469 $meta_where['item_id'] = array_keys( $entries );
470 }
471
472 $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' );
473
474 unset( $meta_where );
475
476 if ( ! $metas ) {
477 self::prepare_entries( $entries );
478 return $entries;
479 }
480
481 foreach ( $metas as $m_key => $meta_val ) {
482 if ( ! isset( $entries[ $meta_val->item_id ] ) ) {
483 continue;
484 }
485
486 if ( ! isset( $entries[ $meta_val->item_id ]->metas ) ) {
487 $entries[ $meta_val->item_id ]->metas = array();
488 }
489
490 FrmAppHelper::unserialize_or_decode( $meta_val->meta_value );
491 $entries[ $meta_val->item_id ]->metas[ $meta_val->field_id ] = $meta_val->meta_value;
492 unset( $m_key, $meta_val );
493 }
494
495 if ( ! FrmAppHelper::prevent_caching() ) {
496 foreach ( $entries as $entry ) {
497 FrmDb::set_cache( $entry->id, $entry, 'frm_entry' );
498 unset( $entry );
499 }
500 }
501
502 self::prepare_entries( $entries );
503 return $entries;
504 }
505
506 // Pagination Methods
507 /**
508 * @param int|array|string If int, use the form id.
509 */
510 public static function getRecordCount( $where = '' ) {
511 global $wpdb;
512 $table_join = $wpdb->prefix . 'frm_items it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id';
513
514 if ( is_numeric( $where ) ) {
515 $table_join = 'frm_items';
516 $where = array( 'form_id' => $where );
517 }
518
519 if ( is_array( $where ) ) {
520 $count = FrmDb::get_count( $table_join, $where );
521 } else {
522 $cache_key = 'count_' . FrmAppHelper::maybe_json_encode( $where );
523 $query = 'SELECT COUNT(*) FROM ' . $table_join . FrmDb::prepend_and_or_where( ' WHERE ', $where );
524 $count = FrmDb::check_cache( $cache_key, 'frm_entry', $query, 'get_var' );
525 }
526
527 return $count;
528 }
529
530 public static function getPageCount( $p_size, $where = '' ) {
531 $p_size = (int) $p_size;
532 $count = 1;
533 if ( $p_size ) {
534 if ( ! is_numeric( $where ) ) {
535 $where = self::getRecordCount( $where );
536 }
537 $count = ceil( (int) $where / $p_size );
538 }
539
540 return $count;
541 }
542
543 /**
544 * Prepare the data before inserting it into the database
545 *
546 * @since 2.0.16
547 *
548 * @param array $values
549 * @param string $type
550 *
551 * @return array $new_values
552 */
553 private static function before_insert_entry_in_database( &$values, $type ) {
554
555 self::sanitize_entry_post( $values );
556
557 if ( $type != 'xml' ) {
558 $values = apply_filters( 'frm_pre_create_entry', $values );
559 }
560
561 $new_values = self::package_entry_data( $values );
562
563 return $new_values;
564 }
565
566 /**
567 * Create an entry and perform after create actions
568 *
569 * @since 2.0.16
570 *
571 * @param array $values
572 * @param array $new_values
573 *
574 * @return boolean|int $entry_id
575 */
576 private static function continue_to_create_entry( $values, $new_values ) {
577 $entry_id = self::insert_entry_into_database( $new_values );
578 if ( ! $entry_id ) {
579 return false;
580 }
581
582 self::after_insert_entry_in_database( $values, $new_values, $entry_id );
583
584 return $entry_id;
585 }
586
587 /**
588 * Sanitize the POST values before we use them
589 *
590 * @since 2.0
591 *
592 * @param array $values The POST values by reference
593 */
594 public static function sanitize_entry_post( &$values ) {
595 $sanitize_method = array(
596 'form_id' => 'absint',
597 'frm_action' => 'sanitize_title',
598 'form_key' => 'sanitize_title',
599 'item_key' => 'sanitize_title',
600 'item_name' => 'sanitize_text_field',
601 'frm_saving_draft' => 'absint',
602 'is_draft' => 'absint',
603 'post_id' => 'absint',
604 'parent_item_id' => 'absint',
605 'created_at' => 'sanitize_text_field',
606 'updated_at' => 'sanitize_text_field',
607 );
608
609 FrmAppHelper::sanitize_request( $sanitize_method, $values );
610 }
611
612 /**
613 * Prepare the new values for inserting into the database
614 *
615 * @since 2.0.16
616 *
617 * @param array $values
618 *
619 * @return array $new_values
620 */
621 private static function package_entry_data( &$values ) {
622 global $wpdb;
623
624 if ( ! isset( $values['item_key'] ) ) {
625 $values['item_key'] = '';
626 }
627
628 $item_name = self::get_new_entry_name( $values, $values['item_key'] );
629 $new_values = array(
630 'item_key' => FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key' ),
631 'name' => FrmAppHelper::truncate( $item_name, 255, 1, '' ),
632 'ip' => self::get_ip( $values ),
633 'is_draft' => self::get_is_draft_value( $values ),
634 'form_id' => (int) self::get_entry_value( $values, 'form_id', null ),
635 'post_id' => (int) self::get_entry_value( $values, 'post_id', 0 ),
636 'parent_item_id' => (int) self::get_entry_value( $values, 'parent_item_id', 0 ),
637 'created_at' => self::get_created_at( $values ),
638 'updated_at' => self::get_updated_at( $values ),
639 'description' => self::get_entry_description( $values ),
640 'user_id' => self::get_entry_user_id( $values ),
641 );
642
643 $new_values['updated_by'] = isset( $values['updated_by'] ) ? $values['updated_by'] : $new_values['user_id'];
644
645 return $new_values;
646 }
647
648 private static function get_entry_value( $values, $name, $default ) {
649 return isset( $values[ $name ] ) ? $values[ $name ] : $default;
650 }
651
652 /**
653 * Get the ip for a new entry.
654 * Allow the import to override the value.
655 *
656 * @since 2.03.10
657 *
658 * @param array $values
659 *
660 * @return string
661 */
662 private static function get_ip( $values ) {
663 if ( ! FrmAppHelper::ips_saved() ) {
664 return '';
665 }
666
667 $ip = FrmAppHelper::get_ip_address();
668 if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
669 $ip = self::get_entry_value( $values, 'ip', $ip );
670 }
671
672 return $ip;
673 }
674
675 /**
676 * Get the is_draft value for a new entry
677 *
678 * @since 2.0.16
679 *
680 * @param array $values
681 *
682 * @return int
683 */
684 private static function get_is_draft_value( $values ) {
685 return ( ( isset( $values['frm_saving_draft'] ) && $values['frm_saving_draft'] == 1 ) || ( isset( $values['is_draft'] ) && $values['is_draft'] == 1 ) ) ? 1 : 0;
686 }
687
688 /**
689 * Get the created_at value for a new entry
690 *
691 * @since 2.0.16
692 *
693 * @param array $values
694 *
695 * @return string
696 */
697 private static function get_created_at( $values ) {
698 return self::get_entry_value( $values, 'created_at', current_time( 'mysql', 1 ) );
699 }
700
701 /**
702 * Get the updated_at value for a new entry
703 *
704 * @since 2.0.16
705 *
706 * @param array $values
707 *
708 * @return string
709 */
710 private static function get_updated_at( $values ) {
711 if ( isset( $values['updated_at'] ) ) {
712 $updated_at = $values['updated_at'];
713 } else {
714 $updated_at = self::get_created_at( $values );
715 }
716
717 return $updated_at;
718 }
719
720 /**
721 * Get the description value for a new entry
722 *
723 * @since 2.0.16
724 *
725 * @param array $values
726 *
727 * @return string
728 */
729 private static function get_entry_description( $values ) {
730 if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) {
731 $description = FrmAppHelper::maybe_json_encode( $values['description'] );
732 } else {
733 $description = json_encode(
734 array(
735 'browser' => FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' ),
736 'referrer' => FrmAppHelper::get_server_value( 'HTTP_REFERER' ),
737 )
738 );
739 }
740
741 return $description;
742 }
743
744 /**
745 * Get the user_id value for a new entry
746 *
747 * @since 2.0.16
748 *
749 * @param array $values
750 *
751 * @return int
752 */
753 private static function get_entry_user_id( $values ) {
754 if ( isset( $values['frm_user_id'] ) && ( is_numeric( $values['frm_user_id'] ) || FrmAppHelper::is_admin() ) ) {
755 $user_id = $values['frm_user_id'];
756 } else {
757 $current_user_id = get_current_user_id();
758 $user_id = $current_user_id ? $current_user_id : 0;
759 }
760
761 return $user_id;
762 }
763
764 /**
765 * Insert new entry into the database
766 *
767 * @since 2.0.16
768 *
769 * @param array $new_values
770 *
771 * @return int | boolean $entry_id
772 */
773 private static function insert_entry_into_database( $new_values ) {
774 global $wpdb;
775
776 $query_results = $wpdb->insert( $wpdb->prefix . 'frm_items', $new_values );
777
778 if ( ! $query_results ) {
779 $entry_id = false;
780 } else {
781 $entry_id = $wpdb->insert_id;
782 }
783
784 return $entry_id;
785 }
786
787 /**
788 * Add the new entry to global $frm_vars
789 *
790 * @since 2.0.16
791 *
792 * @param int $entry_id
793 */
794 private static function add_new_entry_to_frm_vars( $entry_id ) {
795 global $frm_vars;
796
797 if ( ! isset( $frm_vars['saved_entries'] ) ) {
798 $frm_vars['saved_entries'] = array();
799 }
800
801 $frm_vars['saved_entries'][] = (int) $entry_id;
802 }
803
804 /**
805 * Add entry metas, if there are any
806 *
807 * @since 2.0.16
808 *
809 * @param array $values
810 * @param int $entry_id
811 */
812 private static function maybe_add_entry_metas( $values, $entry_id ) {
813 if ( isset( $values['item_meta'] ) ) {
814 FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] );
815 }
816 }
817
818 /**
819 * Trigger frm_after_create_entry hooks
820 *
821 * @since 2.0.16
822 *
823 * @param int $entry_id
824 * @param array $new_values
825 */
826 private static function after_entry_created_actions( $entry_id, $values, $new_values ) {
827 // this is a child entry
828 $is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' );
829
830 do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) );
831 do_action( 'frm_after_create_entry_' . $new_values['form_id'], $entry_id, compact( 'is_child' ) );
832 }
833
834 /**
835 * Actions to perform immediately after an entry is inserted in the frm_items database
836 *
837 * @since 2.0.16
838 *
839 * @param array $values
840 * @param array $new_values
841 * @param int $entry_id
842 */
843 private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) {
844
845 self::add_new_entry_to_frm_vars( $entry_id );
846
847 self::maybe_add_entry_metas( $values, $entry_id );
848
849 self::clear_cache();
850
851 self::after_entry_created_actions( $entry_id, $values, $new_values );
852 }
853
854 /**
855 * Perform some actions right before updating an entry
856 *
857 * @since 2.0.16
858 *
859 * @param int $id
860 * @param array $values
861 * @param string $update_type
862 *
863 * @return boolean $update
864 */
865 private static function before_update_entry( $id, &$values, $update_type ) {
866 $update = true;
867
868 global $frm_vars;
869
870 if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) {
871 $update = false;
872 }
873
874 if ( $update && $update_type != 'xml' ) {
875 $values = apply_filters( 'frm_pre_update_entry', $values, $id );
876 }
877
878 return $update;
879 }
880
881 /**
882 * Package the entry data for updating
883 *
884 * @since 2.0.16
885 *
886 * @param int $id
887 * @param array $values
888 *
889 * @return array $new_values
890 */
891 private static function package_entry_to_update( $id, $values ) {
892 global $wpdb;
893
894 $new_values = array(
895 'name' => self::get_new_entry_name( $values ),
896 'form_id' => (int) self::get_entry_value( $values, 'form_id', null ),
897 'is_draft' => self::get_is_draft_value( $values ),
898 'updated_at' => current_time( 'mysql', 1 ),
899 'updated_by' => isset( $values['updated_by'] ) ? $values['updated_by'] : get_current_user_id(),
900 );
901
902 if ( isset( $values['post_id'] ) ) {
903 $new_values['post_id'] = (int) $values['post_id'];
904 }
905
906 if ( isset( $values['item_key'] ) ) {
907 $new_values['item_key'] = FrmAppHelper::get_unique_key( $values['item_key'], $wpdb->prefix . 'frm_items', 'item_key', $id );
908 }
909
910 if ( isset( $values['parent_item_id'] ) ) {
911 $new_values['parent_item_id'] = (int) $values['parent_item_id'];
912 }
913
914 if ( isset( $values['frm_user_id'] ) && is_numeric( $values['frm_user_id'] ) ) {
915 $new_values['user_id'] = $values['frm_user_id'];
916 }
917
918 $new_values = apply_filters( 'frm_update_entry', $new_values, $id );
919
920 return $new_values;
921 }
922
923 /**
924 * Perform some actions right after updating an entry
925 *
926 * @since 2.0.16
927 *
928 * @param boolean|int $query_results
929 * @param int $id
930 * @param array $values
931 * @param array $new_values
932 */
933 private static function after_update_entry( $query_results, $id, $values, $new_values ) {
934 if ( $query_results ) {
935 self::clear_cache();
936 }
937
938 global $frm_vars;
939 if ( ! isset( $frm_vars['saved_entries'] ) ) {
940 $frm_vars['saved_entries'] = array();
941 }
942
943 $frm_vars['saved_entries'][] = (int) $id;
944
945 if ( isset( $values['item_meta'] ) ) {
946 FrmEntryMeta::update_entry_metas( $id, $values['item_meta'] );
947 }
948
949 do_action( 'frm_after_update_entry', $id, $new_values['form_id'] );
950 do_action( 'frm_after_update_entry_' . $new_values['form_id'], $id );
951 }
952
953 /**
954 * Create entry from an XML import
955 * Certain actions aren't necessary when importing (like saving sub entries, checking for duplicates, etc.)
956 *
957 * @since 2.0.16
958 *
959 * @param array $values
960 *
961 * @return int | boolean $entry_id
962 */
963 public static function create_entry_from_xml( $values ) {
964 $entry_id = self::create_entry( $values, 'xml' );
965
966 return $entry_id;
967 }
968
969 /**
970 * Update entry from an XML import
971 * Certain actions aren't necessary when importing (like saving sub entries and modifying other vals)
972 *
973 * @since 2.0.16
974 *
975 * @param int $id
976 * @param array $values
977 *
978 * @return int | boolean $updated
979 */
980 public static function update_entry_from_xml( $id, $values ) {
981 $updated = self::update_entry( $id, $values, 'xml' );
982
983 return $updated;
984 }
985
986 /**
987 * @param string $key
988 *
989 * @return int entry_id
990 */
991 public static function get_id_by_key( $key ) {
992 $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) );
993
994 return (int) $entry_id;
995 }
996 }
997