| @@ -5,13 +5,20 @@ | ||
| 5 | 5 | |
| 6 | 6 | class FrmEntry { |
| 7 | 7 | |
| 8 | 8 | /** |
| 9 | + * @since 6.16.3 | |
| 10 | + * | |
| 11 | + * @var array | |
| 12 | + */ | |
| 13 | + private static $unique_id_match_checks = array(); | |
| 14 | + | |
| 15 | + /** | |
| 9 | 16 | * Create a new entry |
| 10 | 17 | * |
| 11 | 18 | * @param array $values |
| 12 | 19 | * |
| 13 | - * @return int | boolean $entry_id | |
| 20 | + * @return bool|int $entry_id | |
| 14 | 21 | */ |
| 15 | 22 | public static function create( $values ) { |
| 16 | 23 | $entry_id = self::create_entry( $values, 'standard' ); |
| 17 | 24 | |
| @@ -20,18 +27,18 @@ | ||
| 20 | 27 | |
| 21 | 28 | /** |
| 22 | 29 | * Create a new entry with some differences depending on type |
| 23 | 30 | * |
| 24 | - * @param array $values | |
| 31 | + * @param array $values | |
| 25 | 32 | * @param string $type |
| 26 | 33 | * |
| 27 | - * @return int | boolean $entry_id | |
| 34 | + * @return bool|int $entry_id | |
| 28 | 35 | */ |
| 29 | 36 | private static function create_entry( $values, $type ) { |
| 30 | 37 | $new_values = self::before_insert_entry_in_database( $values, $type ); |
| 31 | 38 | |
| 32 | 39 | // Don't check XML entries for duplicates |
| 33 | - if ( $type != 'xml' && self::is_duplicate( $new_values, $values ) ) { | |
| 40 | + if ( $type !== 'xml' && self::is_duplicate( $new_values, $values ) ) { | |
| 34 | 41 | return false; |
| 35 | 42 | } |
| 36 | 43 | |
| 37 | 44 | $entry_id = self::continue_to_create_entry( $values, $new_values ); |
| @@ -39,11 +46,26 @@ | ||
| 39 | 46 | return $entry_id; |
| 40 | 47 | } |
| 41 | 48 | |
| 42 | 49 | /** |
| 50 | + * Flag the memoized unique id check after a new entry is created. | |
| 51 | + * This prevents possibly DB requests and helps avoid issues when creating repeater entries. | |
| 52 | + * | |
| 53 | + * @since 6.16.3 | |
| 54 | + * | |
| 55 | + * @param string $unique_id | |
| 56 | + * @return void | |
| 57 | + */ | |
| 58 | + private static function flag_new_unique_key( $unique_id ) { | |
| 59 | + if ( ! isset( self::$unique_id_match_checks[ $unique_id ] ) ) { | |
| 60 | + self::$unique_id_match_checks[ $unique_id ] = false; | |
| 61 | + } | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 43 | 65 | * Check for duplicate entries created in the last minute |
| 44 | 66 | * |
| 45 | - * @return boolean | |
| 67 | + * @return bool | |
| 46 | 68 | */ |
| 47 | 69 | public static function is_duplicate( $new_values, $values ) { |
| 48 | 70 | $duplicate_entry_time = apply_filters( 'frm_time_to_check_duplicates', 60, $new_values ); |
| 49 | 71 | |
| @@ -50,10 +72,14 @@ | ||
| 50 | 72 | if ( false === self::is_duplicate_check_needed( $values, $duplicate_entry_time ) ) { |
| 51 | 73 | return false; |
| 52 | 74 | } |
| 53 | 75 | |
| 76 | + if ( self::maybe_check_for_unique_id_match( $values, $new_values['created_at'] ) ) { | |
| 77 | + return true; | |
| 78 | + } | |
| 79 | + | |
| 54 | 80 | $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 ) ) ); | |
| 81 | + $check_val['created_at >'] = gmdate( 'Y-m-d H:i:s', strtotime( $new_values['created_at'] ) - absint( $duplicate_entry_time ) ); | |
| 56 | 82 | |
| 57 | 83 | unset( $check_val['created_at'], $check_val['updated_at'], $check_val['is_draft'], $check_val['id'], $check_val['item_key'] ); |
| 58 | 84 | |
| 59 | 85 | if ( $new_values['item_key'] == $new_values['name'] ) { |
| @@ -79,8 +105,11 @@ | ||
| 79 | 105 | // make sure it's a duplicate |
| 80 | 106 | $metas = FrmEntryMeta::get_entry_meta_info( $entry_exist ); |
| 81 | 107 | $field_metas = array(); |
| 82 | 108 | foreach ( $metas as $meta ) { |
| 109 | + if ( 0 === (int) $meta->field_id ) { | |
| 110 | + continue; | |
| 111 | + } | |
| 83 | 112 | $field_metas[ $meta->field_id ] = $meta->meta_value; |
| 84 | 113 | } |
| 85 | 114 | |
| 86 | 115 | $filtered_vals = array_filter( $values['item_meta'] ); |
| @@ -106,12 +135,11 @@ | ||
| 106 | 135 | continue; |
| 107 | 136 | } |
| 108 | 137 | |
| 109 | 138 | $diff = array_diff_assoc( $field_metas, $new_meta ); |
| 110 | - foreach ( $diff as $field_id => $meta_value ) { | |
| 139 | + foreach ( $diff as $meta_value ) { | |
| 111 | 140 | if ( ! empty( $meta_value ) ) { |
| 112 | 141 | $is_duplicate = false; |
| 113 | - continue; | |
| 114 | 142 | } |
| 115 | 143 | } |
| 116 | 144 | |
| 117 | 145 | if ( $is_duplicate ) { |
| @@ -116,9 +144,9 @@ | ||
| 116 | 144 | |
| 117 | 145 | if ( $is_duplicate ) { |
| 118 | 146 | break; |
| 119 | 147 | } |
| 120 | - } | |
| 148 | + }//end foreach | |
| 121 | 149 | |
| 122 | 150 | $frm_vars['checking_duplicates'] = false; |
| 123 | 151 | |
| 124 | 152 | return $is_duplicate; |
| @@ -124,8 +152,67 @@ | ||
| 124 | 152 | return $is_duplicate; |
| 125 | 153 | } |
| 126 | 154 | |
| 127 | 155 | /** |
| 156 | + * @since 6.16.3 | |
| 157 | + * | |
| 158 | + * @param array $values POST request data. | |
| 159 | + * @param string $created_at The timestamp of the entry we are checking for. | |
| 160 | + * @return bool | |
| 161 | + */ | |
| 162 | + private static function maybe_check_for_unique_id_match( $values, $created_at ) { | |
| 163 | + if ( ! self::should_check_for_unique_id_match() ) { | |
| 164 | + return false; | |
| 165 | + } | |
| 166 | + | |
| 167 | + if ( empty( $values['unique_id'] ) ) { | |
| 168 | + return false; | |
| 169 | + } | |
| 170 | + | |
| 171 | + $unique_id = sanitize_key( $values['unique_id'] ); | |
| 172 | + if ( ! $unique_id ) { | |
| 173 | + // Only continue if a unique ID was generated on form submit. | |
| 174 | + return false; | |
| 175 | + } | |
| 176 | + | |
| 177 | + if ( isset( self::$unique_id_match_checks[ $unique_id ] ) ) { | |
| 178 | + return self::$unique_id_match_checks[ $unique_id ]; | |
| 179 | + } | |
| 180 | + | |
| 181 | + $timestamp = strtotime( $created_at ); | |
| 182 | + if ( false === $timestamp ) { | |
| 183 | + $timestamp = time(); | |
| 184 | + } | |
| 185 | + | |
| 186 | + self::$unique_id_match_checks[ $unique_id ] = (bool) FrmDb::get_var( | |
| 187 | + 'frm_item_metas', | |
| 188 | + array( | |
| 189 | + 'field_id' => 0, | |
| 190 | + 'meta_value' => serialize( compact( 'unique_id' ) ), | |
| 191 | + 'created_at >' => gmdate( 'Y-m-d H:i:s', $timestamp - MONTH_IN_SECONDS ), | |
| 192 | + ), | |
| 193 | + 'id' | |
| 194 | + ); | |
| 195 | + | |
| 196 | + return self::$unique_id_match_checks[ $unique_id ]; | |
| 197 | + } | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * @since 6.16.3 | |
| 201 | + */ | |
| 202 | + private static function should_check_for_unique_id_match() { | |
| 203 | + /** | |
| 204 | + * Allow users to opt out of the DB query, in case it causes performance issues. | |
| 205 | + * | |
| 206 | + * @since 6.16.3 | |
| 207 | + * | |
| 208 | + * @param bool $should_extend | |
| 209 | + */ | |
| 210 | + $should_check = apply_filters( 'frm_check_for_unique_id_match', true ); | |
| 211 | + return (bool) $should_check; | |
| 212 | + } | |
| 213 | + | |
| 214 | + /** | |
| 128 | 215 | * Convert form data to the actual value that would be saved into the database. |
| 129 | 216 | * This is important for the duplicate check as something like 'a:2:{s:5:"typed";s:0:"";s:6:"output";s:0:"";}' (a signature value) is actually an empty string and does not get saved. |
| 130 | 217 | * |
| 131 | 218 | * @param array $filter_vals |
| @@ -150,9 +237,9 @@ | ||
| 150 | 237 | * |
| 151 | 238 | * @since 2.0.23 |
| 152 | 239 | * |
| 153 | 240 | * @param array $values |
| 154 | - * @param int $duplicate_entry_time | |
| 241 | + * @param int $duplicate_entry_time | |
| 155 | 242 | * |
| 156 | 243 | * @return bool |
| 157 | 244 | */ |
| 158 | 245 | private static function is_duplicate_check_needed( $values, $duplicate_entry_time ) { |
| @@ -212,12 +299,12 @@ | ||
| 212 | 299 | |
| 213 | 300 | /** |
| 214 | 301 | * Update an entry (not via XML) |
| 215 | 302 | * |
| 216 | - * @param int $id | |
| 303 | + * @param int $id | |
| 217 | 304 | * @param array $values |
| 218 | 305 | * |
| 219 | - * @return boolean|int $update_results | |
| 306 | + * @return bool|int $update_results | |
| 220 | 307 | */ |
| 221 | 308 | public static function update( $id, $values ) { |
| 222 | 309 | $update_results = self::update_entry( $id, $values, 'standard' ); |
| 223 | 310 | |
| @@ -228,12 +315,12 @@ | ||
| 228 | 315 | * Update an entry with some differences depending on the update type |
| 229 | 316 | * |
| 230 | 317 | * @since 2.0.16 |
| 231 | 318 | * |
| 232 | - * @param int $id | |
| 319 | + * @param int $id | |
| 233 | 320 | * @param array $values |
| 234 | 321 | * |
| 235 | - * @return boolean|int $query_results | |
| 322 | + * @return bool|int $query_results | |
| 236 | 323 | */ |
| 237 | 324 | private static function update_entry( $id, $values, $update_type ) { |
| 238 | 325 | global $wpdb; |
| 239 | 326 | |
| @@ -253,9 +340,9 @@ | ||
| 253 | 340 | |
| 254 | 341 | /** |
| 255 | 342 | * Delete an entry. |
| 256 | 343 | * |
| 257 | - * @param string|int $id | |
| 344 | + * @param int|string $id | |
| 258 | 345 | * @return bool True on success, false if nothing was deleted. |
| 259 | 346 | */ |
| 260 | 347 | public static function destroy( $id ) { |
| 261 | 348 | global $wpdb; |
| @@ -260,9 +347,10 @@ | ||
| 260 | 347 | public static function destroy( $id ) { |
| 261 | 348 | global $wpdb; |
| 262 | 349 | $id = (int) $id; |
| 263 | 350 | |
| 264 | - $entry = self::getOne( $id, true ); // Item meta is required for conditional logic in actions with 'delete' events. | |
| 351 | + // Item meta is required for conditional logic in actions with 'delete' events. | |
| 352 | + $entry = self::getOne( $id, true ); | |
| 265 | 353 | if ( ! $entry ) { |
| 266 | 354 | $result = false; |
| 267 | 355 | return $result; |
| 268 | 356 | } |
| @@ -335,11 +423,12 @@ | ||
| 335 | 423 | |
| 336 | 424 | /** |
| 337 | 425 | * If $entry is numeric, get the entry object |
| 338 | 426 | * |
| 339 | - * @param int|object $entry by reference | |
| 427 | + * @since 2.0.9 | |
| 340 | 428 | * |
| 341 | - * @since 2.0.9 | |
| 429 | + * @param int|object $entry By reference. | |
| 430 | + * @return void | |
| 342 | 431 | */ |
| 343 | 432 | public static function maybe_get_entry( &$entry ) { |
| 344 | 433 | if ( $entry && is_numeric( $entry ) ) { |
| 345 | 434 | $entry = self::getOne( $entry ); |
| @@ -353,9 +442,9 @@ | ||
| 353 | 442 | |
| 354 | 443 | $query = "SELECT it.*, fr.name as form_name, fr.form_key as form_key FROM {$wpdb->prefix}frm_items it |
| 355 | 444 | LEFT OUTER JOIN {$wpdb->prefix}frm_forms fr ON it.form_id=fr.id WHERE "; |
| 356 | 445 | |
| 357 | - $query .= is_numeric( $id ) ? 'it.id=%d' : 'it.item_key=%s'; | |
| 446 | + $query .= is_numeric( $id ) ? 'it.id=%d' : 'it.item_key=%s'; | |
| 358 | 447 | $query_args = array( $id ); |
| 359 | 448 | $query = $wpdb->prepare( $query, $query_args ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 360 | 449 | |
| 361 | 450 | if ( ! $meta ) { |
| @@ -387,9 +476,10 @@ | ||
| 387 | 476 | return; |
| 388 | 477 | } |
| 389 | 478 | |
| 390 | 479 | FrmAppHelper::unserialize_or_decode( $entry->description ); |
| 391 | - $entry = wp_unslash( $entry ); // TODO: Remove slashes on input only, not output. | |
| 480 | + // TODO: Remove slashes on input only, not output. | |
| 481 | + $entry = wp_unslash( $entry ); | |
| 392 | 482 | } |
| 393 | 483 | |
| 394 | 484 | /** |
| 395 | 485 | * @since 4.02.03 |
| @@ -466,9 +556,9 @@ | ||
| 466 | 556 | $where = array( 'item_key' => $id ); |
| 467 | 557 | } |
| 468 | 558 | $id = FrmDb::get_var( $wpdb->prefix . 'frm_items', $where ); |
| 469 | 559 | |
| 470 | - return ( $id && $id > 0 ); | |
| 560 | + return $id && $id > 0; | |
| 471 | 561 | } |
| 472 | 562 | |
| 473 | 563 | public static function getAll( $where, $order_by = '', $limit = '', $meta = false, $inc_form = true ) { |
| 474 | 564 | global $wpdb; |
| @@ -483,9 +573,9 @@ | ||
| 483 | 573 | $table = $wpdb->prefix . 'frm_items it '; |
| 484 | 574 | |
| 485 | 575 | if ( $inc_form ) { |
| 486 | 576 | $fields = 'it.*, fr.name as form_name,fr.form_key as form_key'; |
| 487 | - $table .= 'LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id '; | |
| 577 | + $table .= 'LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id '; | |
| 488 | 578 | } |
| 489 | 579 | |
| 490 | 580 | if ( preg_match( '/ meta_([0-9]+)/', $order_by, $order_matches ) ) { |
| 491 | 581 | $fields .= self::sort_by_field( $order_matches[1] ); |
| @@ -498,9 +588,9 @@ | ||
| 498 | 588 | $entries = $wpdb->get_results( $query, OBJECT_K ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 499 | 589 | unset( $query ); |
| 500 | 590 | |
| 501 | 591 | FrmDb::set_cache( $cache_key, $entries, 'frm_entry' ); |
| 502 | - } | |
| 592 | + }//end if | |
| 503 | 593 | |
| 504 | 594 | if ( ! $meta || ! $entries ) { |
| 505 | 595 | self::prepare_entries( $entries ); |
| 506 | 596 | return $entries; |
| @@ -577,13 +667,14 @@ | ||
| 577 | 667 | } |
| 578 | 668 | |
| 579 | 669 | // Pagination Methods |
| 580 | 670 | /** |
| 581 | - * @param int|array|string If int, use the form id. | |
| 671 | + * @param array|int|string $where If int, use the form id. | |
| 672 | + * @return int|string | |
| 582 | 673 | */ |
| 583 | 674 | public static function getRecordCount( $where = '' ) { |
| 584 | 675 | global $wpdb; |
| 585 | - $table_join = $wpdb->prefix . 'frm_items it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id'; | |
| 676 | + $table_join = $wpdb->prefix . 'frm_items it JOIN ' . $wpdb->prefix . 'frm_forms fr ON it.form_id=fr.id'; | |
| 586 | 677 | |
| 587 | 678 | if ( is_numeric( $where ) ) { |
| 588 | 679 | $table_join = 'frm_items'; |
| 589 | 680 | $where = array( 'form_id' => $where ); |
| @@ -599,8 +690,12 @@ | ||
| 599 | 690 | |
| 600 | 691 | return $count; |
| 601 | 692 | } |
| 602 | 693 | |
| 694 | + /** | |
| 695 | + * @param int|string $p_size | |
| 696 | + * @return int | |
| 697 | + */ | |
| 603 | 698 | public static function getPageCount( $p_size, $where = '' ) { |
| 604 | 699 | $p_size = (int) $p_size; |
| 605 | 700 | $count = 1; |
| 606 | 701 | if ( $p_size ) { |
| @@ -617,9 +712,9 @@ | ||
| 617 | 712 | * Prepare the data before inserting it into the database |
| 618 | 713 | * |
| 619 | 714 | * @since 2.0.16 |
| 620 | 715 | * |
| 621 | - * @param array $values | |
| 716 | + * @param array $values | |
| 622 | 717 | * @param string $type |
| 623 | 718 | * |
| 624 | 719 | * @return array $new_values |
| 625 | 720 | */ |
| @@ -626,9 +721,9 @@ | ||
| 626 | 721 | private static function before_insert_entry_in_database( &$values, $type ) { |
| 627 | 722 | |
| 628 | 723 | self::sanitize_entry_post( $values ); |
| 629 | 724 | |
| 630 | - if ( $type != 'xml' ) { | |
| 725 | + if ( $type !== 'xml' ) { | |
| 631 | 726 | $values = apply_filters( 'frm_pre_create_entry', $values ); |
| 632 | 727 | } |
| 633 | 728 | |
| 634 | 729 | $new_values = self::package_entry_data( $values ); |
| @@ -643,9 +738,9 @@ | ||
| 643 | 738 | * |
| 644 | 739 | * @param array $values |
| 645 | 740 | * @param array $new_values |
| 646 | 741 | * |
| 647 | - * @return boolean|int $entry_id | |
| 742 | + * @return bool|int $entry_id | |
| 648 | 743 | */ |
| 649 | 744 | private static function continue_to_create_entry( $values, $new_values ) { |
| 650 | 745 | $entry_id = self::insert_entry_into_database( $new_values ); |
| 651 | 746 | if ( ! $entry_id ) { |
| @@ -661,9 +756,9 @@ | ||
| 661 | 756 | * Sanitize the POST values before we use them |
| 662 | 757 | * |
| 663 | 758 | * @since 2.0 |
| 664 | 759 | * |
| 665 | - * @param array $values The POST values by reference | |
| 760 | + * @param array $values The POST values by reference. | |
| 666 | 761 | */ |
| 667 | 762 | public static function sanitize_entry_post( &$values ) { |
| 668 | 763 | $sanitize_method = array( |
| 669 | 764 | 'form_id' => 'absint', |
| @@ -803,9 +898,9 @@ | ||
| 803 | 898 | * |
| 804 | 899 | * @return string |
| 805 | 900 | */ |
| 806 | 901 | private static function get_entry_description( $values ) { |
| 807 | - if ( isset( $values['description'] ) && ! empty( $values['description'] ) ) { | |
| 902 | + if ( ! empty( $values['description'] ) ) { | |
| 808 | 903 | $description = FrmAppHelper::maybe_json_encode( $values['description'] ); |
| 809 | 904 | } else { |
| 810 | 905 | $description = json_encode( |
| 811 | 906 | array( |
| @@ -844,9 +939,9 @@ | ||
| 844 | 939 | * @since 2.0.16 |
| 845 | 940 | * |
| 846 | 941 | * @param array $new_values |
| 847 | 942 | * |
| 848 | - * @return int | boolean $entry_id | |
| 943 | + * @return bool|int $entry_id | |
| 849 | 944 | */ |
| 850 | 945 | private static function insert_entry_into_database( $new_values ) { |
| 851 | 946 | global $wpdb; |
| 852 | 947 | |
| @@ -883,19 +978,41 @@ | ||
| 883 | 978 | * |
| 884 | 979 | * @since 2.0.16 |
| 885 | 980 | * |
| 886 | 981 | * @param array $values |
| 887 | - * @param int $entry_id | |
| 982 | + * @param int $entry_id | |
| 888 | 983 | * @return void |
| 889 | 984 | */ |
| 890 | 985 | private static function maybe_add_entry_metas( $values, $entry_id ) { |
| 891 | 986 | if ( isset( $values['item_meta'] ) ) { |
| 892 | 987 | FrmEntryMeta::update_entry_metas( $entry_id, $values['item_meta'] ); |
| 988 | + self::maybe_add_unique_id_meta( $values, $entry_id ); | |
| 893 | 989 | } |
| 894 | 990 | self::maybe_add_captcha_meta( (int) $values['form_id'], (int) $entry_id ); |
| 895 | 991 | } |
| 896 | 992 | |
| 897 | 993 | /** |
| 994 | + * @since 6.16.3 | |
| 995 | + * | |
| 996 | + * @param array $values | |
| 997 | + * @param int $entry_id | |
| 998 | + * @return void | |
| 999 | + */ | |
| 1000 | + private static function maybe_add_unique_id_meta( $values, $entry_id ) { | |
| 1001 | + if ( ! empty( $values['parent_form_id'] ) || empty( $values['unique_id'] ) || ! self::should_check_for_unique_id_match() ) { | |
| 1002 | + return; | |
| 1003 | + } | |
| 1004 | + | |
| 1005 | + // This unique ID is inserted with JS on form submit. | |
| 1006 | + // It is used to check for duplicate entries. | |
| 1007 | + $unique_id = sanitize_key( $values['unique_id'] ); | |
| 1008 | + if ( $unique_id ) { | |
| 1009 | + FrmEntryMeta::add_entry_meta( $entry_id, 0, '', compact( 'unique_id' ) ); | |
| 1010 | + self::flag_new_unique_key( $unique_id ); | |
| 1011 | + } | |
| 1012 | + } | |
| 1013 | + | |
| 1014 | + /** | |
| 898 | 1015 | * @since 5.0.15 |
| 899 | 1016 | * |
| 900 | 1017 | * @param int $form_id |
| 901 | 1018 | * @param int $entry_id |
| @@ -913,14 +1030,15 @@ | ||
| 913 | 1030 | * Trigger frm_after_create_entry hooks |
| 914 | 1031 | * |
| 915 | 1032 | * @since 2.0.16 |
| 916 | 1033 | * |
| 917 | - * @param int $entry_id | |
| 1034 | + * @param int $entry_id | |
| 1035 | + * @param array $values | |
| 918 | 1036 | * @param array $new_values |
| 919 | 1037 | */ |
| 920 | 1038 | private static function after_entry_created_actions( $entry_id, $values, $new_values ) { |
| 921 | - // this is a child entry | |
| 922 | - $is_child = isset( $values['parent_form_id'] ) && isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' ); | |
| 1039 | + // This is a child entry. | |
| 1040 | + $is_child = isset( $values['parent_nonce'] ) && ! empty( $values['parent_form_id'] ) && wp_verify_nonce( $values['parent_nonce'], 'parent' ); | |
| 923 | 1041 | |
| 924 | 1042 | do_action( 'frm_after_create_entry', $entry_id, $new_values['form_id'], compact( 'is_child' ) ); |
| 925 | 1043 | do_action( 'frm_after_create_entry_' . $new_values['form_id'], $entry_id, compact( 'is_child' ) ); |
| 926 | 1044 | } |
| @@ -931,9 +1049,9 @@ | ||
| 931 | 1049 | * @since 2.0.16 |
| 932 | 1050 | * |
| 933 | 1051 | * @param array $values |
| 934 | 1052 | * @param array $new_values |
| 935 | - * @param int $entry_id | |
| 1053 | + * @param int $entry_id | |
| 936 | 1054 | */ |
| 937 | 1055 | private static function after_insert_entry_in_database( $values, $new_values, $entry_id ) { |
| 938 | 1056 | |
| 939 | 1057 | self::add_new_entry_to_frm_vars( $entry_id ); |
| @@ -949,13 +1067,13 @@ | ||
| 949 | 1067 | * Perform some actions right before updating an entry |
| 950 | 1068 | * |
| 951 | 1069 | * @since 2.0.16 |
| 952 | 1070 | * |
| 953 | - * @param int $id | |
| 954 | - * @param array $values | |
| 1071 | + * @param int $id | |
| 1072 | + * @param array $values | |
| 955 | 1073 | * @param string $update_type |
| 956 | 1074 | * |
| 957 | - * @return boolean $update | |
| 1075 | + * @return bool $update | |
| 958 | 1076 | */ |
| 959 | 1077 | private static function before_update_entry( $id, &$values, $update_type ) { |
| 960 | 1078 | $update = true; |
| 961 | 1079 | |
| @@ -960,13 +1078,13 @@ | ||
| 960 | 1078 | $update = true; |
| 961 | 1079 | |
| 962 | 1080 | global $frm_vars; |
| 963 | 1081 | |
| 964 | - if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, (array) $frm_vars['saved_entries'] ) ) { | |
| 1082 | + if ( isset( $frm_vars['saved_entries'] ) && is_array( $frm_vars['saved_entries'] ) && in_array( (int) $id, $frm_vars['saved_entries'] ) ) { | |
| 965 | 1083 | $update = false; |
| 966 | 1084 | } |
| 967 | 1085 | |
| 968 | - if ( $update && $update_type != 'xml' ) { | |
| 1086 | + if ( $update && $update_type !== 'xml' ) { | |
| 969 | 1087 | $values = apply_filters( 'frm_pre_update_entry', $values, $id ); |
| 970 | 1088 | } |
| 971 | 1089 | |
| 972 | 1090 | return $update; |
| @@ -976,9 +1094,9 @@ | ||
| 976 | 1094 | * Package the entry data for updating |
| 977 | 1095 | * |
| 978 | 1096 | * @since 2.0.16 |
| 979 | 1097 | * |
| 980 | - * @param int $id | |
| 1098 | + * @param int $id | |
| 981 | 1099 | * @param array $values |
| 982 | 1100 | * |
| 983 | 1101 | * @return array $new_values |
| 984 | 1102 | */ |
| @@ -1018,12 +1136,12 @@ | ||
| 1018 | 1136 | * Perform some actions right after updating an entry |
| 1019 | 1137 | * |
| 1020 | 1138 | * @since 2.0.16 |
| 1021 | 1139 | * |
| 1022 | - * @param boolean|int $query_results | |
| 1023 | - * @param int $id | |
| 1024 | - * @param array $values | |
| 1025 | - * @param array $new_values | |
| 1140 | + * @param bool|int $query_results | |
| 1141 | + * @param int $id | |
| 1142 | + * @param array $values | |
| 1143 | + * @param array $new_values | |
| 1026 | 1144 | */ |
| 1027 | 1145 | private static function after_update_entry( $query_results, $id, $values, $new_values ) { |
| 1028 | 1146 | if ( $query_results ) { |
| 1029 | 1147 | self::clear_cache(); |
| @@ -1051,9 +1169,9 @@ | ||
| 1051 | 1169 | * @since 2.0.16 |
| 1052 | 1170 | * |
| 1053 | 1171 | * @param array $values |
| 1054 | 1172 | * |
| 1055 | - * @return int | boolean $entry_id | |
| 1173 | + * @return bool|int $entry_id | |
| 1056 | 1174 | */ |
| 1057 | 1175 | public static function create_entry_from_xml( $values ) { |
| 1058 | 1176 | $entry_id = self::create_entry( $values, 'xml' ); |
| 1059 | 1177 | |
| @@ -1065,12 +1183,12 @@ | ||
| 1065 | 1183 | * Certain actions aren't necessary when importing (like saving sub entries and modifying other vals) |
| 1066 | 1184 | * |
| 1067 | 1185 | * @since 2.0.16 |
| 1068 | 1186 | * |
| 1069 | - * @param int $id | |
| 1187 | + * @param int $id | |
| 1070 | 1188 | * @param array $values |
| 1071 | 1189 | * |
| 1072 | - * @return int | boolean $updated | |
| 1190 | + * @return bool|int $updated | |
| 1073 | 1191 | */ |
| 1074 | 1192 | public static function update_entry_from_xml( $id, $values ) { |
| 1075 | 1193 | $updated = self::update_entry( $id, $values, 'xml' ); |
| 1076 | 1194 | |
| @@ -1085,6 +1203,22 @@ | ||
| 1085 | 1203 | public static function get_id_by_key( $key ) { |
| 1086 | 1204 | $entry_id = FrmDb::get_var( 'frm_items', array( 'item_key' => sanitize_title( $key ) ) ); |
| 1087 | 1205 | |
| 1088 | 1206 | return (int) $entry_id; |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + /** | |
| 1210 | + * Get entries count. | |
| 1211 | + * | |
| 1212 | + * @since 6.8 | |
| 1213 | + * | |
| 1214 | + * @return int|string | |
| 1215 | + */ | |
| 1216 | + public static function get_entries_count() { | |
| 1217 | + $args = array( | |
| 1218 | + 'or' => 1, | |
| 1219 | + 'parent_form_id' => null, | |
| 1220 | + 'parent_form_id <' => 1, | |
| 1221 | + ); | |
| 1222 | + return self::getRecordCount( $args ); | |
| 1089 | 1223 | } |
| 1090 | 1224 | } |