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

480 lines 14.2 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
170 /**
171 * Allows changing entry duplicate values before save.
172 *
173 * @since 5.4.4
174 *
175 * @param array $metas The list of entry meta values.
176 */
177 $metas = apply_filters( 'frm_before_duplicate_entry_values', $metas );
178 foreach ( $metas as $meta ) {
179 self::add_entry_meta( $new_id, $meta->field_id, '', $meta->meta_value );
180 unset( $meta );
181 }
182 self::clear_cache();
183 }
184
185 public static function delete_entry_meta( $entry_id, $field_id ) {
186 global $wpdb;
187 self::clear_cache();
188
189 return $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}frm_item_metas WHERE field_id=%d AND item_id=%d", $field_id, $entry_id ) );
190 }
191
192 /**
193 * Clear entry meta caching
194 * Called when a meta is added or changed
195 *
196 * @since 2.0.5
197 */
198 public static function clear_cache() {
199 FrmDb::cache_delete_group( 'frm_entry_meta' );
200 FrmDb::cache_delete_group( 'frm_item_meta' );
201 }
202
203 /**
204 * @since 2.0.9
205 */
206 public static function get_meta_value( $entry, $field_id ) {
207 if ( isset( $entry->metas ) ) {
208 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 }
212 }
213
214 public static function get_entry_meta_by_field( $entry_id, $field_id ) {
215 global $wpdb;
216
217 if ( is_object( $entry_id ) ) {
218 $entry = $entry_id;
219 $entry_id = $entry->id;
220 $cached = $entry;
221 } else {
222 $entry_id = (int) $entry_id;
223 $cached = FrmDb::check_cache( $entry_id, 'frm_entry' );
224 }
225
226 if ( $cached && isset( $cached->metas ) && isset( $cached->metas[ $field_id ] ) ) {
227 $result = $cached->metas[ $field_id ];
228
229 return wp_unslash( $result );
230 }
231
232 $get_table = $wpdb->prefix . 'frm_item_metas';
233 $query = array( 'item_id' => $entry_id );
234 if ( is_numeric( $field_id ) ) {
235 $query['field_id'] = $field_id;
236 } else {
237 $get_table .= ' it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
238 $query['fi.field_key'] = $field_id;
239 }
240
241 $result = FrmDb::get_var( $get_table, $query, 'meta_value' );
242 FrmAppHelper::unserialize_or_decode( $result );
243 $result = wp_unslash( $result );
244
245 return $result;
246 }
247
248 public static function get_entry_metas_for_field( $field_id, $order = '', $limit = '', $args = array() ) {
249 $defaults = array(
250 'value' => false,
251 'unique' => false,
252 'stripslashes' => true,
253 'is_draft' => false,
254 );
255 $args = wp_parse_args( $args, $defaults );
256
257 $query = array();
258 self::meta_field_query( $field_id, $order, $limit, $args, $query );
259 $query = implode( ' ', $query );
260
261 $cache_key = 'entry_metas_for_field_' . $field_id . $order . $limit . FrmAppHelper::maybe_json_encode( $args );
262 $values = FrmDb::check_cache( $cache_key, 'frm_entry', $query, 'get_col' );
263
264 if ( ! $args['stripslashes'] ) {
265 return $values;
266 }
267
268 foreach ( $values as $k => $v ) {
269 FrmAppHelper::unserialize_or_decode( $v );
270 $values[ $k ] = $v;
271 unset( $k, $v );
272 }
273
274 return wp_unslash( $values );
275 }
276
277 /**
278 * @param string $order
279 * @param string $limit
280 */
281 private static function meta_field_query( $field_id, $order, $limit, $args, array &$query ) {
282 global $wpdb;
283 $query[] = 'SELECT';
284 $query[] = $args['unique'] ? 'DISTINCT(em.meta_value)' : 'em.meta_value';
285 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas em ';
286
287 if ( ! $args['is_draft'] ) {
288 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=em.item_id)';
289 }
290
291 if ( is_numeric( $field_id ) ) {
292 $query[] = $wpdb->prepare( 'WHERE em.field_id=%d', $field_id );
293 } else {
294 $query[] = $wpdb->prepare( 'LEFT JOIN ' . $wpdb->prefix . 'frm_fields fi ON (em.field_id = fi.id) WHERE fi.field_key=%s', $field_id );
295 }
296
297 if ( ! $args['is_draft'] ) {
298 $query[] = 'AND e.is_draft=0';
299 }
300
301 if ( $args['value'] ) {
302 $query[] = $wpdb->prepare( ' AND meta_value=%s', $args['value'] );
303 }
304 $query[] = $order . $limit;
305 }
306
307 public static function get_entry_meta_info( $entry_id ) {
308 return FrmDb::get_results( 'frm_item_metas', array( 'item_id' => $entry_id ) );
309 }
310
311 public static function getAll( $where = array(), $order_by = '', $limit = '', $stripslashes = false ) {
312 global $wpdb;
313 $query = 'SELECT it.*, fi.type as field_type, fi.field_key as field_key,
314 fi.required as required, fi.form_id as field_form_id, fi.name as field_name, fi.options as fi_options
315 FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id' .
316 FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
317
318 $cache_key = 'all_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . $limit;
319 $results = FrmDb::check_cache( $cache_key, 'frm_entry', $query, ( $limit == ' LIMIT 1' ? 'get_row' : 'get_results' ) );
320
321 if ( ! $results || ! $stripslashes ) {
322 return $results;
323 }
324
325 foreach ( $results as $k => $result ) {
326 FrmAppHelper::unserialize_or_decode( $result->meta_value );
327 $results[ $k ]->meta_value = wp_unslash( $result->meta_value );
328 unset( $k, $result );
329 }
330
331 return $results;
332 }
333
334 public static function getEntryIds( $where = array(), $order_by = '', $limit = '', $unique = true, $args = array() ) {
335 $defaults = array(
336 'is_draft' => false,
337 'user_id' => '',
338 'group_by' => '',
339 );
340 $args = wp_parse_args( $args, $defaults );
341
342 $query = array();
343 self::get_ids_query( $where, $order_by, $limit, $unique, $args, $query );
344 $query = implode( ' ', $query );
345
346 $cache_key = 'ids_' . FrmAppHelper::maybe_json_encode( $where ) . $order_by . 'l' . $limit . 'u' . $unique . FrmAppHelper::maybe_json_encode( $args );
347 $type = 'get_' . ( ' LIMIT 1' === $limit ? 'var' : 'col' );
348 return FrmDb::check_cache( $cache_key, 'frm_entry', $query, $type );
349 }
350
351 /**
352 * Given a query including a form id and its child form ids, output an array of matching entry ids
353 * If a child entry id is matched, its parent will be returned in its place
354 *
355 * @param array $query
356 * @param array $args
357 * @return array
358 */
359 public static function get_top_level_entry_ids( $query, $args ) {
360 $args['return_parent_id_if_0_return_id'] = true;
361 return self::getEntryIds( $query, '', '', true, $args );
362 }
363
364 /**
365 * @param string|array $where
366 * @param string $order_by
367 * @param string $limit
368 */
369 private static function get_ids_query( $where, $order_by, $limit, $unique, $args, array &$query ) {
370 global $wpdb;
371 $query[] = 'SELECT';
372 $defaults = array(
373 'return_parent_id' => false,
374 'return_parent_id_if_0_return_id' => false,
375 );
376 $args = array_merge( $defaults, $args );
377
378 if ( $unique ) {
379 $query[] = 'DISTINCT';
380 }
381
382 if ( $args['return_parent_id_if_0_return_id'] ) {
383 $query[] = 'IF ( e.parent_item_id = 0, it.item_id, e.parent_item_id )';
384 } elseif ( $args['return_parent_id'] ) {
385 $query[] = 'e.parent_item_id';
386 } else {
387 $query[] = 'it.item_id';
388 }
389
390 $query[] = 'FROM ' . $wpdb->prefix . 'frm_item_metas it LEFT OUTER JOIN ' . $wpdb->prefix . 'frm_fields fi ON it.field_id=fi.id';
391
392 $query[] = 'INNER JOIN ' . $wpdb->prefix . 'frm_items e ON (e.id=it.item_id)';
393 if ( is_array( $where ) ) {
394 if ( ! $args['is_draft'] ) {
395 $where['e.is_draft'] = 0;
396 } elseif ( $args['is_draft'] == 1 ) {
397 $where['e.is_draft'] = 1;
398 }
399
400 if ( ! empty( $args['user_id'] ) ) {
401 $where['e.user_id'] = $args['user_id'];
402 }
403 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
404
405 if ( $args['group_by'] ) {
406 $query[] = ' GROUP BY ' . sanitize_text_field( $args['group_by'] );
407 }
408
409 return;
410 }
411
412 $draft_where = '';
413 $user_where = '';
414 if ( ! $args['is_draft'] ) {
415 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 0 );
416 } elseif ( $args['is_draft'] == 1 ) {
417 $draft_where = $wpdb->prepare( ' AND e.is_draft=%d', 1 );
418 }
419
420 if ( ! empty( $args['user_id'] ) ) {
421 $user_where = $wpdb->prepare( ' AND e.user_id=%d', $args['user_id'] );
422 }
423
424 if ( strpos( $where, ' GROUP BY ' ) ) {
425 // don't inject WHERE filtering after GROUP BY
426 $parts = explode( ' GROUP BY ', $where );
427 $where = $parts[0];
428 $where .= $draft_where . $user_where;
429 $where .= ' GROUP BY ' . $parts[1];
430 } else {
431 $where .= $draft_where . $user_where;
432 }
433
434 // The query has already been prepared
435 $query[] = FrmDb::prepend_and_or_where( ' WHERE ', $where ) . $order_by . $limit;
436 }
437
438 public static function search_entry_metas( $search, $field_id, $operator ) {
439 $cache_key = 'search_' . FrmAppHelper::maybe_json_encode( $search ) . $field_id . $operator;
440 $results = wp_cache_get( $cache_key, 'frm_entry' );
441 if ( false !== $results ) {
442 return $results;
443 }
444
445 global $wpdb;
446 if ( is_array( $search ) ) {
447 $where = '';
448 foreach ( $search as $field => $value ) {
449 if ( $value <= 0 || ! in_array( $field, array( 'year', 'month', 'day' ) ) ) {
450 continue;
451 }
452
453 switch ( $field ) {
454 case 'year':
455 $value = '%' . $value;
456 break;
457 case 'month':
458 $value .= '%';
459 break;
460 case 'day':
461 $value = '%' . $value . '%';
462 }
463 $where .= $wpdb->prepare( ' meta_value ' . $operator . ' %s and', $value ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
464 }
465 $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 );
467 } else {
468 if ( $operator == 'LIKE' ) {
469 $search = '%' . $search . '%';
470 }
471 $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 }
473
474 $results = $wpdb->get_col( $query, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
475 FrmDb::set_cache( $cache_key, $results, 'frm_entry' );
476
477 return $results;
478 }
479 }
480