PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.18
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.18
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
← All changes | classes/models/FrmEntryMeta.php +128 -34 6.36.18 View file →
@@ -9,8 +9,9 @@
9 9 * @param int $entry_id
10 10 * @param int $field_id
11 11 * @param string $meta_key usually set to '' as this parameter is no longer used.
12 12 * @param mixed $meta_value
13 + * @return int
13 14 */
14 15 public static function add_entry_meta( $entry_id, $field_id, $meta_key, $meta_value ) {
15 16 global $wpdb;
16 17
@@ -42,11 +43,11 @@
42 43 return $id;
43 44 }
44 45
45 46 /**
46 - * @param int $entry_id
47 - * @param int $field_id
48 - * @param string $meta_key deprecated
47 + * @param int $entry_id
48 + * @param int $field_id
49 + * @param string $meta_key Deprecated.
49 50 * @param array|string $meta_value
50 51 *
51 52 * @return bool|false|int
52 53 */
@@ -106,13 +107,18 @@
106 107
107 108 $value = apply_filters( 'frm_prepare_data_before_db', $value, $atts['field_id'], $atts['entry_id'], array( 'field' => $atts['field'] ) );
108 109 }
109 110
111 + /**
112 + * @param int|string $entry_id
113 + * @param array $values Either indexed by field ID or field key.
114 + * @return void
115 + */
110 116 public static function update_entry_metas( $entry_id, $values ) {
111 117 global $wpdb;
112 118
113 - $prev_values = FrmDb::get_col(
114 - $wpdb->prefix . 'frm_item_metas',
119 + $previous_field_ids = FrmDb::get_col(
120 + 'frm_item_metas',
115 121 array(
116 122 'item_id' => $entry_id,
117 123 'field_id !' => 0,
118 124 ),
@@ -118,21 +124,30 @@
118 124 ),
119 125 'field_id'
120 126 );
121 127
122 - foreach ( $values as $field_id => $meta_value ) {
123 - $field = false;
124 - if ( ! empty( $field_id ) ) {
125 - $field = FrmField::getOne( $field_id );
128 + $values_indexed_by_field_id = array();
129 + foreach ( $values as $field_id_or_key => $meta_value ) {
130 + $field_id = $field_id_or_key;
131 + $field = null;
132 +
133 + if ( $field_id_or_key ) {
134 + $field = FrmField::getOne( $field_id_or_key );
135 +
136 + if ( is_object( $field ) ) {
137 + $field_id = $field->id;
138 + }
126 139 }
127 140
141 + $values_indexed_by_field_id[ $field_id ] = $meta_value;
142 +
128 143 self::get_value_to_save( compact( 'field', 'field_id', 'entry_id' ), $meta_value );
129 144
130 - if ( $prev_values && in_array( $field_id, $prev_values ) ) {
145 + if ( $previous_field_ids && in_array( $field_id, $previous_field_ids ) ) {
131 146
132 147 if ( ( is_array( $meta_value ) && empty( $meta_value ) ) || ( ! is_array( $meta_value ) && trim( $meta_value ) == '' ) ) {
133 - // remove blank fields
134 - unset( $values[ $field_id ] );
148 + // Remove blank fields.
149 + unset( $values_indexed_by_field_id[ $field_id ] );
135 150 } else {
136 151 // if value exists, then update it
137 152 self::update_entry_meta( $entry_id, $field_id, '', $meta_value );
138 153 }
@@ -139,17 +154,17 @@
139 154 } else {
140 155 // if value does not exist, then create it
141 156 self::add_entry_meta( $entry_id, $field_id, '', $meta_value );
142 157 }
143 - }
158 + }//end foreach
144 159
145 - if ( empty( $prev_values ) ) {
160 + if ( empty( $previous_field_ids ) ) {
146 161 return;
147 162 }
148 163
149 - $prev_values = array_diff( $prev_values, array_keys( $values ) );
164 + $field_ids_to_remove = array_diff( $previous_field_ids, array_keys( $values_indexed_by_field_id ) );
150 165
151 - if ( empty( $prev_values ) ) {
166 + if ( ! $field_ids_to_remove ) {
152 167 return;
153 168 }
154 169
155 170 // prepare the query
@@ -154,9 +169,9 @@
154 169
155 170 // prepare the query
156 171 $where = array(
157 172 'item_id' => $entry_id,
158 - 'field_id' => $prev_values,
173 + 'field_id' => $field_ids_to_remove,
159 174 );
160 175 FrmDb::get_where_clause_and_values( $where );
161 176
162 177 // Delete any leftovers
@@ -201,17 +216,25 @@
201 216 }
202 217
203 218 /**
204 219 * @since 2.0.9
220 + *
221 + * @param stdClass $entry
222 + * @param int|string $field_id
223 + * @return mixed
205 224 */
206 225 public static function get_meta_value( $entry, $field_id ) {
207 226 if ( isset( $entry->metas ) ) {
208 227 return isset( $entry->metas[ $field_id ] ) ? $entry->metas[ $field_id ] : false;
209 - } else {
210 - return self::get_entry_meta_by_field( $entry->id, $field_id );
211 228 }
229 + return self::get_entry_meta_by_field( $entry->id, $field_id );
212 230 }
213 231
232 + /**
233 + * @param int|object|string $entry_id
234 + * @param int|string $field_id This function supports field keys as field id.
235 + * @return mixed
236 + */
214 237 public static function get_entry_meta_by_field( $entry_id, $field_id ) {
215 238 global $wpdb;
216 239
217 240 if ( is_object( $entry_id ) ) {
@@ -231,16 +254,21 @@
231 254
232 255 $get_table = $wpdb->prefix . 'frm_item_metas';
233 256 $query = array( 'item_id' => $entry_id );
234 257 if ( is_numeric( $field_id ) ) {
258 + // Query by field ID.
235 259 $query['field_id'] = $field_id;
236 260 } else {
237 - $get_table .= ' it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
261 + // Query by field key.
262 + $get_table .= ' it JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
238 263 $query['fi.field_key'] = $field_id;
239 264 }
240 265
241 266 $result = FrmDb::get_var( $get_table, $query, 'meta_value' );
242 - FrmAppHelper::unserialize_or_decode( $result );
267 +
268 + $field_type = FrmField::get_type( $field_id );
269 + FrmFieldsHelper::prepare_field_value( $result, $field_type );
270 +
243 271 $result = wp_unslash( $result );
244 272
245 273 return $result;
246 274 }
@@ -274,10 +302,13 @@
274 302 return wp_unslash( $values );
275 303 }
276 304
277 305 /**
278 - * @param string $order
279 - * @param string $limit
306 + * @param int|string $field_id
307 + * @param string $order
308 + * @param string $limit
309 + * @param array $args
310 + * @param array $query
280 311 */
281 312 private static function meta_field_query( $field_id, $order, $limit, $args, array &$query ) {
282 313 global $wpdb;
283 314 $query[] = 'SELECT';
@@ -307,8 +338,15 @@
307 338 public static function get_entry_meta_info( $entry_id ) {
308 339 return FrmDb::get_results( 'frm_item_metas', array( 'item_id' => $entry_id ) );
309 340 }
310 341
342 + /**
343 + * @param array $where
344 + * @param string $order_by
345 + * @param string $limit
346 + * @param bool $stripslashes
347 + * @return array
348 + */
311 349 public static function getAll( $where = array(), $order_by = '', $limit = '', $stripslashes = false ) {
312 350 global $wpdb;
313 351 $query = 'SELECT it.*, fi.type as field_type, fi.field_key as field_key,
314 352 fi.required as required, fi.form_id as field_form_id, fi.name as field_name, fi.options as fi_options
@@ -361,12 +399,41 @@
361 399 return self::getEntryIds( $query, '', '', true, $args );
362 400 }
363 401
364 402 /**
365 - * @param string|array $where
366 - * @param string $order_by
367 - * @param string $limit
403 + * Returns true if the where clause refers to a field table column that is not form_id. It also updates
404 + * the where clause to refer to the entry table for form_id if fields table should not be joined.
405 + *
406 + * @since 6.16.1
407 + * @param array|string $where
408 + * @return bool
368 409 */
410 + private static function should_join_fields_table( &$where ) {
411 + if ( is_string( $where ) ) {
412 + if ( preg_match( '/\bfi\.(?!form_id)\w+/i', $where ) ) {
413 + return true;
414 + }
415 + $where = str_ireplace( 'fi.form_id', 'e.form_id', $where );
416 + return false;
417 + }
418 + $where_fields = array_keys( $where );
419 + foreach ( $where_fields as $where_field ) {
420 + if ( strpos( $where_field, 'fi.' ) === 0 && 'fi.form_id' !== $where_field ) {
421 + return true;
422 + }
423 + }
424 + if ( isset( $where['fi.form_id'] ) ) {
425 + $where['e.form_id'] = $where['fi.form_id'];
426 + unset( $where['fi.form_id'] );
427 + }
428 + return false;
429 + }
430 +
431 + /**
432 + * @param array|string $where
433 + * @param string $order_by
434 + * @param string $limit
435 + */
369 436 private static function get_ids_query( $where, $order_by, $limit, $unique, $args, array &$query ) {
370 437 global $wpdb;
371 438 $query[] = 'SELECT';
372 439 $defaults = array(
@@ -386,17 +453,44 @@
386 453 } else {
387 454 $query[] = 'it.item_id';
388 455 }
389 456
390 - $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
457 + $from = 'FROM ' . $wpdb->prefix . 'frm_item_metas it';
391 458
459 + $should_join_fields_table__where = self::should_join_fields_table( $where );
460 + $should_join_fields_table__order_by = self::should_join_fields_table( $order_by );
461 + if ( $should_join_fields_table__where || $should_join_fields_table__order_by ) {
462 + $from .= ' LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
463 + }
464 +
465 + $query[] = $from;
392 466 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=it.item_id)';
393 467 if ( is_array( $where ) ) {
394 468 if ( ! $args['is_draft'] ) {
395 469 $where['e.is_draft'] = 0;
396 - } elseif ( $args['is_draft'] == 1 ) {
397 - $where['e.is_draft'] = 1;
398 - }
470 + } elseif ( is_numeric( $args['is_draft'] ) ) {
471 + if ( class_exists( 'FrmAbandonmentHooksController', false ) ) {
472 + $where['e.is_draft'] = absint( $args['is_draft'] );
473 + } else {
474 + $where['e.is_draft'] = 1;
475 + }
476 + } elseif ( 'both' === $args['is_draft'] && class_exists( 'FrmAbandonmentHooksController', false ) ) {
477 + $where['e.is_draft'] = array( 0, 1 );
478 + } elseif ( false !== strpos( $args['is_draft'], ',' ) ) {
479 + $is_draft = array_reduce(
480 + explode( ',', $args['is_draft'] ),
481 + function ( $total, $current ) {
482 + if ( is_numeric( $current ) ) {
483 + $total[] = absint( $current );
484 + }
485 + return $total;
486 + },
487 + array()
488 + );
489 + if ( $is_draft ) {
490 + $where['e.is_draft'] = $is_draft;
491 + }
492 + }//end if
399 493
400 494 if ( ! empty( $args['user_id'] ) ) {
401 495 $where['e.user_id'] = $args['user_id'];
402 496 }
@@ -406,9 +500,9 @@
406 500 $query[] = ' GROUP BY ' . sanitize_text_field( $args['group_by'] );
407 501 }
408 502
409 503 return;
410 - }
504 + }//end if
411 505
412 506 $draft_where = '';
413 507 $user_where = '';
414 508 if ( ! $args['is_draft'] ) {
@@ -462,15 +556,15 @@
462 556 }
463 557 $where .= $wpdb->prepare( ' meta_value ' . $operator . ' %s and', $value ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
464 558 }
465 559 $where .= $wpdb->prepare( ' field_id=%d', $field_id );
466 - $query = 'SELECT DISTINCT item_id FROM ' . $wpdb->prefix . 'frm_item_metas' . FrmDb::prepend_and_or_where( ' WHERE ', $where );
560 + $query = 'SELECT DISTINCT item_id FROM ' . $wpdb->prefix . 'frm_item_metas' . FrmDb::prepend_and_or_where( ' WHERE ', $where );
467 561 } else {
468 - if ( $operator == 'LIKE' ) {
562 + if ( $operator === 'LIKE' ) {
469 563 $search = '%' . $search . '%';
470 564 }
471 565 $query = $wpdb->prepare( "SELECT DISTINCT item_id FROM {$wpdb->prefix}frm_item_metas WHERE meta_value {$operator} %s and field_id = %d", $search, $field_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
472 - }
566 + }//end if
473 567
474 568 $results = $wpdb->get_col( $query, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
475 569 FrmDb::set_cache( $cache_key, $results, 'frm_entry' );
476 570