PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.10
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.10
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 / FrmEntryMeta.php

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

514 lines 15.3 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 FrmEntryMeta {
7
8 /**
9 * @param int $entry_id
10 * @param int $field_id
11 * @param string $meta_key usually set to '' as this parameter is no longer used.
12 * @param mixed $meta_value
13 * @return int
14 */
15 public static function add_entry_meta( $entry_id, $field_id, $meta_key, $meta_value ) {
16 global $wpdb;
17
18 if ( FrmAppHelper::is_empty_value( $meta_value ) ) {
19 // don't save blank fields
20 return 0;
21 }
22
23 $new_values = array(
24 'meta_value' => is_array( $meta_value ) ? serialize( array_filter( $meta_value, 'FrmAppHelper::is_not_empty_value' ) ) : trim( $meta_value ),
25 'item_id' => $entry_id,
26 'field_id' => $field_id,
27 'created_at' => current_time( 'mysql', 1 ),
28 );
29
30 self::set_value_before_save( $new_values );
31 $new_values = apply_filters( 'frm_add_entry_meta', $new_values );
32
33 $query_results = $wpdb->insert( $wpdb->prefix . 'frm_item_metas', $new_values );
34
35 if ( $query_results ) {
36 self::clear_cache();
37 wp_cache_delete( $entry_id, 'frm_entry' );
38 $id = $wpdb->insert_id;
39 } else {
40 $id = 0;
41 }
42
43 return $id;
44 }
45
46 /**
47 * @param int $entry_id
48 * @param int $field_id
49 * @param string $meta_key Deprecated.
50 * @param array|string $meta_value
51 *
52 * @return bool|false|int
53 */
54 public static function update_entry_meta( $entry_id, $field_id, $meta_key, $meta_value ) {
55 if ( ! $field_id ) {
56 return false;
57 }
58
59 global $wpdb;
60
61 $values = array(
62 'item_id' => $entry_id,
63 'field_id' => $field_id,
64 );
65 $where_values = $values;
66 $values['meta_value'] = $meta_value;
67 self::set_value_before_save( $values );
68 $values = apply_filters( 'frm_update_entry_meta', $values );
69
70 if ( is_array( $values['meta_value'] ) ) {
71 $values['meta_value'] = array_filter( $values['meta_value'], 'FrmAppHelper::is_not_empty_value' );
72 }
73 $meta_value = maybe_serialize( $values['meta_value'] );
74
75 wp_cache_delete( $entry_id, 'frm_entry' );
76 self::clear_cache();
77
78 return $wpdb->update( $wpdb->prefix . 'frm_item_metas', array( 'meta_value' => $meta_value ), $where_values );
79 }
80
81 /**
82 * @since 3.0
83 */
84 private static function set_value_before_save( &$values ) {
85 $field = FrmField::getOne( $values['field_id'] );
86 if ( $field ) {
87 $field_obj = FrmFieldFactory::get_field_object( $field );
88
89 $values['meta_value'] = $field_obj->set_value_before_save( $values['meta_value'] );
90 }
91 }
92
93 /**
94 * @since 3.0
95 */
96 private static function get_value_to_save( $atts, &$value ) {
97 if ( is_object( $atts['field'] ) ) {
98 $field_obj = FrmFieldFactory::get_field_object( $atts['field'] );
99 $value = $field_obj->get_value_to_save(
100 $value,
101 array(
102 'entry_id' => $atts['entry_id'],
103 'field_id' => $atts['field_id'],
104 )
105 );
106 }
107
108 $value = apply_filters( 'frm_prepare_data_before_db', $value, $atts['field_id'], $atts['entry_id'], array( 'field' => $atts['field'] ) );
109 }
110
111 public static function update_entry_metas( $entry_id, $values ) {
112 global $wpdb;
113
114 $prev_values = FrmDb::get_col(
115 $wpdb->prefix . 'frm_item_metas',
116 array(
117 'item_id' => $entry_id,
118 'field_id !' => 0,
119 ),
120 'field_id'
121 );
122
123 foreach ( $values as $field_id => $meta_value ) {
124 $field = false;
125 if ( ! empty( $field_id ) ) {
126 $field = FrmField::getOne( $field_id );
127 }
128
129 self::get_value_to_save( compact( 'field', 'field_id', 'entry_id' ), $meta_value );
130
131 if ( $prev_values && in_array( $field_id, $prev_values ) ) {
132
133 if ( ( is_array( $meta_value ) && empty( $meta_value ) ) || ( ! is_array( $meta_value ) && trim( $meta_value ) == '' ) ) {
134 // remove blank fields
135 unset( $values[ $field_id ] );
136 } else {
137 // if value exists, then update it
138 self::update_entry_meta( $entry_id, $field_id, '', $meta_value );
139 }
140 } else {
141 // if value does not exist, then create it
142 self::add_entry_meta( $entry_id, $field_id, '', $meta_value );
143 }
144 }//end foreach
145
146 if ( empty( $prev_values ) ) {
147 return;
148 }
149
150 $prev_values = array_diff( $prev_values, array_keys( $values ) );
151
152 if ( empty( $prev_values ) ) {
153 return;
154 }
155
156 // prepare the query
157 $where = array(
158 'item_id' => $entry_id,
159 'field_id' => $prev_values,
160 );
161 FrmDb::get_where_clause_and_values( $where );
162
163 // Delete any leftovers
164 $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas ' . $where['where'], $where['values'] ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
165 self::clear_cache();
166 }
167
168 public static function duplicate_entry_metas( $old_id, $new_id ) {
169 $metas = self::get_entry_meta_info( $old_id );
170
171 /**
172 * Allows changing entry duplicate values before save.
173 *
174 * @since 5.4.4
175 *
176 * @param array $metas The list of entry meta values.
177 */
178 $metas = apply_filters( 'frm_before_duplicate_entry_values', $metas );
179 foreach ( $metas as $meta ) {
180 self::add_entry_meta( $new_id, $meta->field_id, '', $meta->meta_value );
181 unset( $meta );
182 }
183 self::clear_cache();
184 }
185
186 public static function delete_entry_meta( $entry_id, $field_id ) {
187 global $wpdb;
188 self::clear_cache();
189
190 return $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}frm_item_metas WHERE field_id=%d AND item_id=%d", $field_id, $entry_id ) );
191 }
192
193 /**
194 * Clear entry meta caching
195 * Called when a meta is added or changed
196 *
197 * @since 2.0.5
198 */
199 public static function clear_cache() {
200 FrmDb::cache_delete_group( 'frm_entry_meta' );
201 FrmDb::cache_delete_group( 'frm_item_meta' );
202 }
203
204 /**
205 * @since 2.0.9
206 *
207 * @param stdClass $entry
208 * @param int|string $field_id
209 * @return mixed
210 */
211 public static function get_meta_value( $entry, $field_id ) {
212 if ( isset( $entry->metas ) ) {
213 return isset( $entry->metas[ $field_id ] ) ? $entry->metas[ $field_id ] : false;
214 }
215 return self::get_entry_meta_by_field( $entry->id, $field_id );
216 }
217
218 public static function get_entry_meta_by_field( $entry_id, $field_id ) {
219 global $wpdb;
220
221 if ( is_object( $entry_id ) ) {
222 $entry = $entry_id;
223 $entry_id = $entry->id;
224 $cached = $entry;
225 } else {
226 $entry_id = (int) $entry_id;
227 $cached = FrmDb::check_cache( $entry_id, 'frm_entry' );
228 }
229
230 if ( $cached && isset( $cached->metas ) && isset( $cached->metas[ $field_id ] ) ) {
231 $result = $cached->metas[ $field_id ];
232
233 return wp_unslash( $result );
234 }
235
236 $get_table = $wpdb->prefix . 'frm_item_metas';
237 $query = array( 'item_id' => $entry_id );
238 if ( is_numeric( $field_id ) ) {
239 $query['field_id'] = $field_id;
240 } else {
241 $get_table .= ' it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
242 $query['fi.field_key'] = $field_id;
243 }
244
245 $result = FrmDb::get_var( $get_table, $query, 'meta_value' );
246 FrmAppHelper::unserialize_or_decode( $result );
247 $result = wp_unslash( $result );
248
249 return $result;
250 }
251
252 public static function get_entry_metas_for_field( $field_id, $order = '', $limit = '', $args = array() ) {
253 $defaults = array(
254 'value' => false,
255 'unique' => false,
256 'stripslashes' => true,
257 'is_draft' => false,
258 );
259 $args = wp_parse_args( $args, $defaults );
260
261 $query = array();
262 self::meta_field_query( $field_id, $order, $limit, $args, $query );
263 $query = implode( ' ', $query );
264
265 $cache_key = 'entry_metas_for_field_' . $field_id . $order . $limit . FrmAppHelper::maybe_json_encode( $args );
266 $values = FrmDb::check_cache( $cache_key, 'frm_entry', $query, 'get_col' );
267
268 if ( ! $args['stripslashes'] ) {
269 return $values;
270 }
271
272 foreach ( $values as $k => $v ) {
273 FrmAppHelper::unserialize_or_decode( $v );
274 $values[ $k ] = $v;
275 unset( $k, $v );
276 }
277
278 return wp_unslash( $values );
279 }
280
281 /**
282 * @param int|string $field_id
283 * @param string $order
284 * @param string $limit
285 * @param array $args
286 * @param array $query
287 */
288 private static function meta_field_query( $field_id, $order, $limit, $args, array &$query ) {
289 global $wpdb;
290 $query[] = 'SELECT';
291 $query[] = $args['unique'] ? 'DISTINCT(em.meta_value)' : 'em.meta_value';
292 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas em ';
293
294 if ( ! $args['is_draft'] ) {
295 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=em.item_id)';
296 }
297
298 if ( is_numeric( $field_id ) ) {
299 $query[] = $wpdb->prepare( 'WHERE em.field_id=%d', $field_id );
300 } else {
301 $query[] = $wpdb->prepare( 'LEFT JOIN ' . $wpdb->prefix . 'frm_fields fi ON (em.field_id = fi.id) WHERE fi.field_key=%s', $field_id );
302 }
303
304 if ( ! $args['is_draft'] ) {
305 $query[] = 'AND e.is_draft=0';
306 }
307
308 if ( $args['value'] ) {
309 $query[] = $wpdb->prepare( ' AND meta_value=%s', $args['value'] );
310 }
311 $query[] = $order . $limit;
312 }
313
314 public static function get_entry_meta_info( $entry_id ) {
315 return FrmDb::get_results( 'frm_item_metas', array( 'item_id' => $entry_id ) );
316 }
317
318 /**
319 * @param array $where
320 * @param string $order_by
321 * @param string $limit
322 * @param bool $stripslashes
323 * @return array
324 */
325 public static function getAll( $where = array(), $order_by = '', $limit = '', $stripslashes = false ) {
326 global $wpdb;
327 $query = 'SELECT it.*, fi.type as field_type, fi.field_key as field_key,
328 fi.required as required, fi.form_id as field_form_id, fi.name as field_name, fi.options as fi_options
329 FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id' .
330 FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
331
332 $cache_key = 'all_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . $limit;
333 $results = FrmDb::check_cache( $cache_key, 'frm_entry', $query, ( $limit == ' LIMIT 1' ? 'get_row' : 'get_results' ) );
334
335 if ( ! $results || ! $stripslashes ) {
336 return $results;
337 }
338
339 foreach ( $results as $k => $result ) {
340 FrmAppHelper::unserialize_or_decode( $result->meta_value );
341 $results[ $k ]->meta_value = wp_unslash( $result->meta_value );
342 unset( $k, $result );
343 }
344
345 return $results;
346 }
347
348 public static function getEntryIds( $where = array(), $order_by = '', $limit = '', $unique = true, $args = array() ) {
349 $defaults = array(
350 'is_draft' => false,
351 'user_id' => '',
352 'group_by' => '',
353 );
354 $args = wp_parse_args( $args, $defaults );
355
356 $query = array();
357 self::get_ids_query( $where, $order_by, $limit, $unique, $args, $query );
358 $query = implode( ' ', $query );
359
360 $cache_key = 'ids_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . 'l' . $limit . 'u' . $unique . FrmAppHelper::maybe_json_encode( $args );
361 $type = 'get_' . ( ' LIMIT 1' === $limit ? 'var' : 'col' );
362 return FrmDb::check_cache( $cache_key, 'frm_entry', $query, $type );
363 }
364
365 /**
366 * Given a query including a form id and its child form ids, output an array of matching entry ids
367 * If a child entry id is matched, its parent will be returned in its place
368 *
369 * @param array $query
370 * @param array $args
371 * @return array
372 */
373 public static function get_top_level_entry_ids( $query, $args ) {
374 $args['return_parent_id_if_0_return_id'] = true;
375 return self::getEntryIds( $query, '', '', true, $args );
376 }
377
378 /**
379 * @param array|string $where
380 * @param string $order_by
381 * @param string $limit
382 */
383 private static function get_ids_query( $where, $order_by, $limit, $unique, $args, array &$query ) {
384 global $wpdb;
385 $query[] = 'SELECT';
386 $defaults = array(
387 'return_parent_id' => false,
388 'return_parent_id_if_0_return_id' => false,
389 );
390 $args = array_merge( $defaults, $args );
391
392 if ( $unique ) {
393 $query[] = 'DISTINCT';
394 }
395
396 if ( $args['return_parent_id_if_0_return_id'] ) {
397 $query[] = 'IF ( e.parent_item_id = 0, it.item_id, e.parent_item_id )';
398 } elseif ( $args['return_parent_id'] ) {
399 $query[] = 'e.parent_item_id';
400 } else {
401 $query[] = 'it.item_id';
402 }
403
404 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
405
406 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=it.item_id)';
407 if ( is_array( $where ) ) {
408 if ( ! $args['is_draft'] ) {
409 $where['e.is_draft'] = 0;
410 } elseif ( is_numeric( $args['is_draft'] ) ) {
411 if ( class_exists( 'FrmAbandonmentHooksController', false ) ) {
412 $where['e.is_draft'] = absint( $args['is_draft'] );
413 } else {
414 $where['e.is_draft'] = 1;
415 }
416 } elseif ( 'both' === $args['is_draft'] && class_exists( 'FrmAbandonmentHooksController', false ) ) {
417 $where['e.is_draft'] = array( 0, 1 );
418 } elseif ( false !== strpos( $args['is_draft'], ',' ) ) {
419 $is_draft = array_reduce(
420 explode( ',', $args['is_draft'] ),
421 function ( $total, $current ) {
422 if ( is_numeric( $current ) ) {
423 $total[] = absint( $current );
424 }
425 return $total;
426 },
427 array()
428 );
429 if ( $is_draft ) {
430 $where['e.is_draft'] = $is_draft;
431 }
432 }//end if
433
434 if ( ! empty( $args['user_id'] ) ) {
435 $where['e.user_id'] = $args['user_id'];
436 }
437 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
438
439 if ( $args['group_by'] ) {
440 $query[] = ' GROUP BY ' . sanitize_text_field( $args['group_by'] );
441 }
442
443 return;
444 }//end if
445
446 $draft_where = '';
447 $user_where = '';
448 if ( ! $args['is_draft'] ) {
449 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 0 );
450 } elseif ( $args['is_draft'] == 1 ) {
451 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 1 );
452 }
453
454 if ( ! empty( $args['user_id'] ) ) {
455 $user_where = $wpdb->prepare( ' AND e.user_id=%d', $args['user_id'] );
456 }
457
458 if ( strpos( $where, ' GROUP BY ' ) ) {
459 // don't inject WHERE filtering after GROUP BY
460 $parts = explode( ' GROUP BY ', $where );
461 $where = $parts[0];
462 $where .= $draft_where . $user_where;
463 $where .= ' GROUP BY ' . $parts[1];
464 } else {
465 $where .= $draft_where . $user_where;
466 }
467
468 // The query has already been prepared
469 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
470 }
471
472 public static function search_entry_metas( $search, $field_id, $operator ) {
473 $cache_key = 'search_' . FrmAppHelper::maybe_json_encode( $search ) . $field_id . $operator;
474 $results = wp_cache_get( $cache_key, 'frm_entry' );
475 if ( false !== $results ) {
476 return $results;
477 }
478
479 global $wpdb;
480 if ( is_array( $search ) ) {
481 $where = '';
482 foreach ( $search as $field => $value ) {
483 if ( $value <= 0 || ! in_array( $field, array( 'year', 'month', 'day' ) ) ) {
484 continue;
485 }
486
487 switch ( $field ) {
488 case 'year':
489 $value = '%' . $value;
490 break;
491 case 'month':
492 $value .= '%';
493 break;
494 case 'day':
495 $value = '%' . $value . '%';
496 }
497 $where .= $wpdb->prepare( ' meta_value ' . $operator . ' %s and', $value ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
498 }
499 $where .= $wpdb->prepare( ' field_id=%d', $field_id );
500 $query = 'SELECT DISTINCT item_id FROM ' . $wpdb->prefix . 'frm_item_metas' . FrmDb::prepend_and_or_where( ' WHERE ', $where );
501 } else {
502 if ( $operator === 'LIKE' ) {
503 $search = '%' . $search . '%';
504 }
505 $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
506 }//end if
507
508 $results = $wpdb->get_col( $query, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
509 FrmDb::set_cache( $cache_key, $results, 'frm_entry' );
510
511 return $results;
512 }
513 }
514