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

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