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

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