PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.9
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.9
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.9, at classes/models/FrmEntryMeta.php

515 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 string|int $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 } else {
215 return self::get_entry_meta_by_field( $entry->id, $field_id );
216 }
217 }
218
219 public static function get_entry_meta_by_field( $entry_id, $field_id ) {
220 global $wpdb;
221
222 if ( is_object( $entry_id ) ) {
223 $entry = $entry_id;
224 $entry_id = $entry->id;
225 $cached = $entry;
226 } else {
227 $entry_id = (int) $entry_id;
228 $cached = FrmDb::check_cache( $entry_id, 'frm_entry' );
229 }
230
231 if ( $cached && isset( $cached->metas ) && isset( $cached->metas[ $field_id ] ) ) {
232 $result = $cached->metas[ $field_id ];
233
234 return wp_unslash( $result );
235 }
236
237 $get_table = $wpdb->prefix . 'frm_item_metas';
238 $query = array( 'item_id' => $entry_id );
239 if ( is_numeric( $field_id ) ) {
240 $query['field_id'] = $field_id;
241 } else {
242 $get_table .= ' it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
243 $query['fi.field_key'] = $field_id;
244 }
245
246 $result = FrmDb::get_var( $get_table, $query, 'meta_value' );
247 FrmAppHelper::unserialize_or_decode( $result );
248 $result = wp_unslash( $result );
249
250 return $result;
251 }
252
253 public static function get_entry_metas_for_field( $field_id, $order = '', $limit = '', $args = array() ) {
254 $defaults = array(
255 'value' => false,
256 'unique' => false,
257 'stripslashes' => true,
258 'is_draft' => false,
259 );
260 $args = wp_parse_args( $args, $defaults );
261
262 $query = array();
263 self::meta_field_query( $field_id, $order, $limit, $args, $query );
264 $query = implode( ' ', $query );
265
266 $cache_key = 'entry_metas_for_field_' . $field_id . $order . $limit . FrmAppHelper::maybe_json_encode( $args );
267 $values = FrmDb::check_cache( $cache_key, 'frm_entry', $query, 'get_col' );
268
269 if ( ! $args['stripslashes'] ) {
270 return $values;
271 }
272
273 foreach ( $values as $k => $v ) {
274 FrmAppHelper::unserialize_or_decode( $v );
275 $values[ $k ] = $v;
276 unset( $k, $v );
277 }
278
279 return wp_unslash( $values );
280 }
281
282 /**
283 * @param string|int $field_id
284 * @param string $order
285 * @param string $limit
286 * @param array $args
287 * @param array $query
288 */
289 private static function meta_field_query( $field_id, $order, $limit, $args, array &$query ) {
290 global $wpdb;
291 $query[] = 'SELECT';
292 $query[] = $args['unique'] ? 'DISTINCT(em.meta_value)' : 'em.meta_value';
293 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas em ';
294
295 if ( ! $args['is_draft'] ) {
296 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=em.item_id)';
297 }
298
299 if ( is_numeric( $field_id ) ) {
300 $query[] = $wpdb->prepare( 'WHERE em.field_id=%d', $field_id );
301 } else {
302 $query[] = $wpdb->prepare( 'LEFT JOIN ' . $wpdb->prefix . 'frm_fields fi ON (em.field_id = fi.id) WHERE fi.field_key=%s', $field_id );
303 }
304
305 if ( ! $args['is_draft'] ) {
306 $query[] = 'AND e.is_draft=0';
307 }
308
309 if ( $args['value'] ) {
310 $query[] = $wpdb->prepare( ' AND meta_value=%s', $args['value'] );
311 }
312 $query[] = $order . $limit;
313 }
314
315 public static function get_entry_meta_info( $entry_id ) {
316 return FrmDb::get_results( 'frm_item_metas', array( 'item_id' => $entry_id ) );
317 }
318
319 /**
320 * @param array $where
321 * @param string $order_by
322 * @param string $limit
323 * @param bool $stripslashes
324 * @return array
325 */
326 public static function getAll( $where = array(), $order_by = '', $limit = '', $stripslashes = false ) {
327 global $wpdb;
328 $query = 'SELECT it.*, fi.type as field_type, fi.field_key as field_key,
329 fi.required as required, fi.form_id as field_form_id, fi.name as field_name, fi.options as fi_options
330 FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id' .
331 FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
332
333 $cache_key = 'all_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . $limit;
334 $results = FrmDb::check_cache( $cache_key, 'frm_entry', $query, ( $limit == ' LIMIT 1' ? 'get_row' : 'get_results' ) );
335
336 if ( ! $results || ! $stripslashes ) {
337 return $results;
338 }
339
340 foreach ( $results as $k => $result ) {
341 FrmAppHelper::unserialize_or_decode( $result->meta_value );
342 $results[ $k ]->meta_value = wp_unslash( $result->meta_value );
343 unset( $k, $result );
344 }
345
346 return $results;
347 }
348
349 public static function getEntryIds( $where = array(), $order_by = '', $limit = '', $unique = true, $args = array() ) {
350 $defaults = array(
351 'is_draft' => false,
352 'user_id' => '',
353 'group_by' => '',
354 );
355 $args = wp_parse_args( $args, $defaults );
356
357 $query = array();
358 self::get_ids_query( $where, $order_by, $limit, $unique, $args, $query );
359 $query = implode( ' ', $query );
360
361 $cache_key = 'ids_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . 'l' . $limit . 'u' . $unique . FrmAppHelper::maybe_json_encode( $args );
362 $type = 'get_' . ( ' LIMIT 1' === $limit ? 'var' : 'col' );
363 return FrmDb::check_cache( $cache_key, 'frm_entry', $query, $type );
364 }
365
366 /**
367 * Given a query including a form id and its child form ids, output an array of matching entry ids
368 * If a child entry id is matched, its parent will be returned in its place
369 *
370 * @param array $query
371 * @param array $args
372 * @return array
373 */
374 public static function get_top_level_entry_ids( $query, $args ) {
375 $args['return_parent_id_if_0_return_id'] = true;
376 return self::getEntryIds( $query, '', '', true, $args );
377 }
378
379 /**
380 * @param string|array $where
381 * @param string $order_by
382 * @param string $limit
383 */
384 private static function get_ids_query( $where, $order_by, $limit, $unique, $args, array &$query ) {
385 global $wpdb;
386 $query[] = 'SELECT';
387 $defaults = array(
388 'return_parent_id' => false,
389 'return_parent_id_if_0_return_id' => false,
390 );
391 $args = array_merge( $defaults, $args );
392
393 if ( $unique ) {
394 $query[] = 'DISTINCT';
395 }
396
397 if ( $args['return_parent_id_if_0_return_id'] ) {
398 $query[] = 'IF ( e.parent_item_id = 0, it.item_id, e.parent_item_id )';
399 } elseif ( $args['return_parent_id'] ) {
400 $query[] = 'e.parent_item_id';
401 } else {
402 $query[] = 'it.item_id';
403 }
404
405 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
406
407 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=it.item_id)';
408 if ( is_array( $where ) ) {
409 if ( ! $args['is_draft'] ) {
410 $where['e.is_draft'] = 0;
411 } elseif ( is_numeric( $args['is_draft'] ) ) {
412 if ( class_exists( 'FrmAbandonmentHooksController', false ) ) {
413 $where['e.is_draft'] = absint( $args['is_draft'] );
414 } else {
415 $where['e.is_draft'] = 1;
416 }
417 } elseif ( 'both' === $args['is_draft'] && class_exists( 'FrmAbandonmentHooksController', false ) ) {
418 $where['e.is_draft'] = array( 0, 1 );
419 } elseif ( false !== strpos( $args['is_draft'], ',' ) ) {
420 $is_draft = array_reduce(
421 explode( ',', $args['is_draft'] ),
422 function ( $total, $current ) {
423 if ( is_numeric( $current ) ) {
424 $total[] = absint( $current );
425 }
426 return $total;
427 },
428 array()
429 );
430 if ( $is_draft ) {
431 $where['e.is_draft'] = $is_draft;
432 }
433 }//end if
434
435 if ( ! empty( $args['user_id'] ) ) {
436 $where['e.user_id'] = $args['user_id'];
437 }
438 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
439
440 if ( $args['group_by'] ) {
441 $query[] = ' GROUP BY ' . sanitize_text_field( $args['group_by'] );
442 }
443
444 return;
445 }//end if
446
447 $draft_where = '';
448 $user_where = '';
449 if ( ! $args['is_draft'] ) {
450 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 0 );
451 } elseif ( $args['is_draft'] == 1 ) {
452 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 1 );
453 }
454
455 if ( ! empty( $args['user_id'] ) ) {
456 $user_where = $wpdb->prepare( ' AND e.user_id=%d', $args['user_id'] );
457 }
458
459 if ( strpos( $where, ' GROUP BY ' ) ) {
460 // don't inject WHERE filtering after GROUP BY
461 $parts = explode( ' GROUP BY ', $where );
462 $where = $parts[0];
463 $where .= $draft_where . $user_where;
464 $where .= ' GROUP BY ' . $parts[1];
465 } else {
466 $where .= $draft_where . $user_where;
467 }
468
469 // The query has already been prepared
470 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
471 }
472
473 public static function search_entry_metas( $search, $field_id, $operator ) {
474 $cache_key = 'search_' . FrmAppHelper::maybe_json_encode( $search ) . $field_id . $operator;
475 $results = wp_cache_get( $cache_key, 'frm_entry' );
476 if ( false !== $results ) {
477 return $results;
478 }
479
480 global $wpdb;
481 if ( is_array( $search ) ) {
482 $where = '';
483 foreach ( $search as $field => $value ) {
484 if ( $value <= 0 || ! in_array( $field, array( 'year', 'month', 'day' ) ) ) {
485 continue;
486 }
487
488 switch ( $field ) {
489 case 'year':
490 $value = '%' . $value;
491 break;
492 case 'month':
493 $value .= '%';
494 break;
495 case 'day':
496 $value = '%' . $value . '%';
497 }
498 $where .= $wpdb->prepare( ' meta_value ' . $operator . ' %s and', $value ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
499 }
500 $where .= $wpdb->prepare( ' field_id=%d', $field_id );
501 $query = 'SELECT DISTINCT item_id FROM ' . $wpdb->prefix . 'frm_item_metas' . FrmDb::prepend_and_or_where( ' WHERE ', $where );
502 } else {
503 if ( $operator == 'LIKE' ) {
504 $search = '%' . $search . '%';
505 }
506 $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
507 }//end if
508
509 $results = $wpdb->get_col( $query, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
510 FrmDb::set_cache( $cache_key, $results, 'frm_entry' );
511
512 return $results;
513 }
514 }
515