PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 3.06.06
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v3.06.06
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 3.06.06, at classes/models/FrmEntry.php

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