PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 7.9.8
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v7.9.8
8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 7.8.7 All 46 releases
gamipress / includes / functions / logs.php

logs.php in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI 7.9.8, at includes/functions/logs.php

1,000 lines 32.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Logs Functions
4 *
5 * @package GamiPress\Logs_Functions
6 * @author GamiPress <[email protected]>, Ruben Garcia <[email protected]>
7 * @since 1.0.0
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 /**
13 * Get an array of log types
14 *
15 * @since 1.0.0
16
17 * @return array The registered logs types
18 */
19 function gamipress_get_log_types() {
20
21 return apply_filters( 'gamipress_logs_types', array(
22 'event_trigger' => __( 'Event Trigger', 'gamipress' ),
23 'achievement_earn' => __( 'Achievement Earn', 'gamipress' ),
24 'achievement_award' => __( 'Achievement Award', 'gamipress' ),
25 'points_earn' => __( 'Points Earn', 'gamipress' ),
26 'points_deduct' => __( 'Points Deduction', 'gamipress' ),
27 'points_expend' => __( 'Points Expend', 'gamipress' ),
28 'points_award' => __( 'Points Award', 'gamipress' ),
29 'points_revoke' => __( 'Points Revoke', 'gamipress' ),
30 'rank_earn' => __( 'Rank Earn', 'gamipress' ),
31 'rank_award' => __( 'Rank Award', 'gamipress' ),
32 ) );
33
34 }
35
36 /**
37 * Get an array of log pattern tags
38 *
39 * @since 1.0.2
40 * @updated 1.3.7 Added the content parameter
41 * @updated 1.8.2 Added the {trigger_type_key} tag
42 *
43 * @param string $context
44 *
45 * @return array The registered log pattern tags
46 */
47 function gamipress_get_log_pattern_tags( $context = 'default' ) {
48
49 return apply_filters( 'gamipress_log_pattern_tags', array(
50 '{user}' => __( 'User assigned.', 'gamipress' ),
51 '{admin}' => __( 'Admin that awards.', 'gamipress' ),
52 '{achievement}' => __( 'Achievement user has earned.', 'gamipress' ),
53 '{achievement_type}' => __( 'Type of the achievement earned.', 'gamipress' ),
54 '{trigger_type}' => __( 'Event triggered label.', 'gamipress' ),
55 '{trigger_type_key}' => __( 'Event triggered internal key.', 'gamipress' ),
56 '{count}' => __( 'Times user triggered this event.', 'gamipress' ),
57 '{points}' => __( 'Points user has earned.', 'gamipress' ),
58 '{points_type}' => __( 'Type of the points earned.', 'gamipress' ),
59 '{total_points}' => __( 'Points user has earned until this log.', 'gamipress' ),
60 '{rank}' => __( 'Rank user has ranked.', 'gamipress' ),
61 '{rank_type}' => __( 'Rank type user has ranked.', 'gamipress' ),
62 '{site_title}' => __( 'Site name.', 'gamipress' ),
63 ), $context );
64
65 }
66
67 /**
68 * Get an array of log pattern tags based on custom context
69 *
70 * @since 1.3.7
71 *
72 * @param array $tags The registered log pattern tags
73 * @param string $context The context
74
75 * @return array Custom log pattern tags by context
76 */
77 function gamipress_get_log_pattern_tags_by_context( $tags, $context = 'default' ) {
78
79 switch( $context ) {
80 case 'deduct':
81 $tags['{points}'] = __( 'Points user has lost.', 'gamipress' );
82 $tags['{points_type}'] = __( 'Type of the points lost.', 'gamipress' );
83 break;
84 case 'expend':
85 $tags['{points}'] = __( 'Points user has expended.', 'gamipress' );
86 $tags['{points_type}'] = __( 'Type of the points expended.', 'gamipress' );
87 break;
88 }
89
90 return $tags;
91
92 }
93 add_filter( 'gamipress_log_pattern_tags', 'gamipress_get_log_pattern_tags_by_context', 10, 2 );
94
95 /**
96 * Get a string with the desired log pattern tags html markup
97 *
98 * @since 1.0.2
99 *
100 * @param array $specific_tags
101 * @param string $context
102 *
103 * @return string Log pattern tags html markup
104 */
105 function gamipress_get_log_pattern_tags_html( $specific_tags = array(), $context = 'default' ) {
106
107 $output = '<ul class="gamipress-log-pattern-tags-list">';
108
109 foreach( gamipress_get_log_pattern_tags( $context ) as $tag => $description ) {
110
111 if( ! empty( $specific_tags ) && ! in_array( $tag, $specific_tags ) ) {
112 continue;
113 }
114
115 $attr_id = 'tag-' . str_replace( array( '{', '}', '_' ), array( '', '', '-' ), $tag );
116
117 $output .= "<li id='{$attr_id}'><code>{$tag}</code> - {$description}</li>";
118 }
119
120 $output .= '</ul>';
121
122 return $output;
123
124 }
125
126 /**
127 * Helper function to easily query logs and centralize code of multiples log query functions
128 *
129 * @since 1.6.0
130 * @updated 1.6.9 Added 'where' and 'get_var' arguments, improvements on query args processing and support to where definition in format: array( 'key' =>'key', 'value' =>'value', 'compare' =>'compare' )
131 * @updated 1.7.6 Added support for array selects, to group_by parameter and the output parameter
132 *
133 * @param array $args
134 *
135 * @return mixed
136 */
137 function gamipress_query_logs( $args ) {
138
139 global $wpdb;
140
141 $logs = GamiPress()->db->logs;
142 $logs_meta = GamiPress()->db->logs_meta;
143
144 $args = wp_parse_args( $args, array(
145 'select' => 'l.id', // You can pass 'l.*', 'l.{field}', 'COUNT(*)' or an array as select
146 'where' => array(), // Supported formats: 'key' =>'value' | array( 'key'=>'key', 'value'=>'value', 'compare'=>'compare', 'type'=>'type' )
147 'date_query' => array(), // Supports before and after parameters
148 'user_id' => 0,
149 'group_by' => '',
150 'order_by' => 'l.date',
151 'order' => 'DESC',
152 'limit' => 0,
153 'since' => 0,
154 'get_var' => false, // Force the use of get_var() function
155 'output' => OBJECT, // Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
156
157 // Deprecated
158 'meta' => array(),
159 ) );
160
161 // Backward compatibility
162 if( isset( $args['meta'] ) && count( $args['meta'] ) ) {
163 $args['where'] = array_merge( $args['where'], $args['meta'] );
164 }
165
166 $log_fields = array(
167 'log_id',
168 'title',
169 'type',
170 'trigger_type',
171 'access',
172 'user_id',
173 'date'
174 );
175
176 if( is_gamipress_upgraded_to( '6.9.4' ) ) {
177 $log_fields[] = 'points';
178 $log_fields[] = 'points_type';
179 }
180
181 // Initialize query definitions
182 $select = array();
183 $joins = array();
184 $where = array();
185 $query_args = array();
186
187 // Select
188 if( is_array( $args['select'] ) ) {
189
190 foreach( $args['select'] as $key => $value ) {
191
192 if( isset( $value['field'] ) ) {
193 $field = $value['field'];
194 } else {
195 $field = $key;
196 }
197
198 if( in_array( $field, $log_fields ) ) {
199 $get_key = "l.{$field}";
200 } else {
201
202 $index = count( $joins );
203
204 $get_key = "lm{$index}.meta_value";
205 $joins[] = "INNER JOIN {$logs_meta} AS lm{$index} ON ( lm{$index}.log_id = l.log_id AND lm{$index}.meta_key = %s )";
206 $query_args[] = $field;
207 }
208
209 if ( isset( $value['function'] ) && $value['function'] ) {
210 $get = "{$value['function']}({$get_key})";
211 } else if ( isset( $value['cast'] ) && $value['cast'] ) {
212 $get = "CAST({$get_key} AS {$value['cast']})";
213 } else {
214 $get = "{$get_key}";
215 }
216
217 $select[] = "{$get} as `{$key}`";
218
219 }
220
221 $args['select'] = ( ! empty( $select ) ? implode( ', ', $select ) : '' );
222 }
223
224 // User ID
225 if( absint( $args['user_id'] ) !== 0 ) {
226
227 $where[] = "l.user_id = %s";
228
229 $query_args[] = $args['user_id'];
230
231 }
232
233 // Where
234
235 if( isset( $args['where'] ) && is_array( $args['where'] ) ) {
236
237 // Loop all log meta to build the where clause
238 foreach ( $args['where'] as $key => $value ) {
239
240 // Field key
241 if( is_array( $value ) && isset( $value['key'] ) ) {
242 $field = $value['key'];
243 } else {
244 $field = $key;
245 }
246
247 // Field value
248 if( is_array( $value ) && isset( $value['value'] ) ) {
249 $field_value = $value['value'];
250 } else {
251 $field_value = $value;
252 }
253
254 // Field compare
255 if( is_array( $field_value ) ) {
256 $default_compare = 'IN';
257 } else {
258 $default_compare = '=';
259 }
260
261 $compare = ( is_array( $value ) && isset( $value['compare'] ) ? $value['compare'] : $default_compare );
262
263 // Field type
264 $default_type = 'string';
265
266 $type = ( is_array( $value ) && isset( $value['type'] ) ? $value['type'] : $default_type );
267
268 // Parse common types to an unique one type
269 switch( $type ) {
270 case 'int':
271 case 'integer':
272 case 'number':
273 case 'numeric':
274 $type = 'integer';
275 break;
276 case 'text':
277 case 'string':
278 case 'char':
279 case 'varchar':
280 default:
281 $type = 'string';
282 break;
283 }
284
285 if( in_array( $field, $log_fields ) ) {
286
287 // Query log field
288
289 if( is_array( $field_value ) ) {
290
291 if( $type === 'integer' ) {
292 $field_value = implode( ", ", $field_value );
293 } else {
294 $field_value = "'" . implode( "', '", $field_value ) . "'";
295 }
296
297 $where[] = "l.{$field} {$compare} ({$field_value})";
298 } else {
299
300 if( $type === 'integer' ) {
301 $where[] = "l.{$field} {$compare} %d";
302 } else {
303 $where[] = "l.{$field} {$compare} %s";
304 }
305
306 $query_args[] = $field_value;
307 }
308
309 } else {
310
311 // Query log meta
312
313 $index = count( $joins );
314
315 $meta_key = '_gamipress_' . sanitize_key( $field );
316
317 // Setup query definitions
318 $joins[] = "LEFT JOIN {$logs_meta} AS lm{$index} ON ( l.log_id = lm{$index}.log_id AND lm{$index}.meta_key = '{$meta_key}' )";
319
320 // If meta value is an array then need to compare using IN operator
321 if( is_array( $field_value ) ) {
322
323 if( $type === 'integer' ) {
324 $field_value = implode( ", ", $field_value );
325 } else {
326 $field_value = "'" . implode( "', '", $field_value ) . "'";
327 }
328
329 $where[] = "lm{$index}.meta_value {$compare} ({$field_value})";
330
331 } else {
332 // Meta query in format: 'key' =>'value'
333 if( $type === 'integer' ) {
334 $where[] = "lm{$index}.meta_value {$compare} %d";
335 } else {
336 $where[] = "lm{$index}.meta_value {$compare} %s";
337 }
338
339 $query_args[] = $field_value;
340 }
341
342 }
343
344 }
345
346 }
347
348 // Date query before
349 if( isset( $args['date_query']['before'] ) && ! empty( $args['date_query']['before'] ) ) {
350 $where[] = "l.date <= %s";
351 $query_args[] = $args['date_query']['before'];
352 }
353
354 // Date query after
355 if( isset( $args['date_query']['after'] ) && ! empty( $args['date_query']['after'] ) ) {
356 $where[] = "l.date >= %s";
357 $query_args[] = $args['date_query']['after'];
358 }
359
360 // Since
361 if( absint( $args['since'] ) > 0 ) {
362 $date = date( 'Y-m-d H:i:s', $args['since'] );
363
364 $where[] = "l.date >= %s";
365 $query_args[] = $date;
366 }
367
368 // Group By
369 $group_by = '';
370
371 if( ! empty( $args['group_by'] ) ) {
372 $group_by = 'GROUP BY ' . $args['group_by'];
373 }
374
375 // Order By
376 $order_by = '';
377
378 if( ! empty( $args['order_by'] ) && ! empty( $args['order'] ) ) {
379 $order_by = 'ORDER BY ' . $args['order_by'] . ' ' . $args['order'];
380 }
381
382 // Turn arrays into strings
383 $select = $args['select'];
384 $joins = implode( ' ', $joins );
385 $where = ( ! empty( $where ) ? 'WHERE ( ' . implode( ' ) AND ( ', $where ) . ' ) ' : '' );
386 $limit = ( absint( $args['limit'] ) !== 0 ? 'LIMIT ' . absint( $args['limit'] ) : '' );
387
388 // Prepare the query SQL
389 $sql = $wpdb->prepare(
390 "SELECT {$select}
391 FROM {$logs} AS l
392 {$joins}
393 {$where}
394 {$group_by}
395 {$order_by}
396 {$limit}",
397 $query_args
398 );
399
400 if( strtoupper( $select ) === 'COUNT(*)' || $args['get_var'] ) {
401 // If is a count, ensure return an integer
402 $logs = absint( $wpdb->get_var( $sql ) );
403 } else {
404 $logs = $wpdb->get_results( $sql, $args['output'] );
405 }
406
407 return $logs;
408
409 }
410
411 /**
412 * Return user logs with the specified meta data
413 *
414 * @since 1.3.7
415 * @updated 1.3.9.6 Added $since parameter
416 * @updated 1.3.9.8 Improvements on since checks
417 * @updated 1.6.0 Code moved to gamipress_query_logs() function
418 *
419 * @param int $user_id
420 * @param array $where
421 * @param int $since
422 *
423 * @return array
424 */
425 function gamipress_get_user_logs( $user_id = 0, $where = array(), $since = 0 ) {
426
427 return gamipress_query_logs( array(
428 'select' => 'l.*',
429 'user_id' => $user_id,
430 'where' => $where,
431 'since' => $since
432 ) );
433
434 }
435
436 /**
437 * Return count of user logs with the specified meta data
438 *
439 * @since 1.1.8
440 * @updated 1.3.7 Added support for multiples types
441 * @updated 1.4.2 Added $since parameter
442 * @updated 1.6.0 Code moved to gamipress_query_logs() function
443 *
444 * @param int $user_id
445 * @param array $where
446 *
447 * @return int
448 */
449 function gamipress_get_user_log_count( $user_id = 0, $where = array(), $since = 0 ) {
450
451 // If not properly upgrade to required version fallback to compatibility function
452 if( ! is_gamipress_upgraded_to( '1.2.8' ) ) {
453 return gamipress_get_user_log_count_old( $user_id, $where );
454 }
455
456 return gamipress_query_logs( array(
457 'select' => 'COUNT(*)',
458 'user_id' => $user_id,
459 'where' => $where,
460 'since' => $since
461 ) );
462
463 }
464
465 /**
466 * Return the last user log with the specified meta data
467 *
468 * @since 1.4.2
469 *
470 * @param int $user_id
471 * @param array $where
472 *
473 * @return stdClass|false
474 */
475 function gamipress_get_user_last_log( $user_id = 0, $where = array() ) {
476
477 $user_logs = gamipress_query_logs( array(
478 'select' => 'l.*',
479 'user_id' => $user_id,
480 'where' => $where,
481 'limit' => 1
482 ) );
483
484 return ( is_array( $user_logs ) && isset( $user_logs[0] ) ? $user_logs[0] : false );
485
486 }
487
488 /**
489 * Posts a log entry when a user unlocks any achievement post
490 *
491 * @since 1.0.0
492 * @updated 1.2.8 Added $type parameter
493 * @updated 1.4.7 Added $trigger_type parameter
494 *
495 * @param string $type The log type
496 * @param int $user_id The user ID
497 * @param string $access Access to this log ( public|private )
498 * @param string $trigger_type Access to this log ( public|private )
499 * @param array $log_meta Log meta data
500 *
501 * @return int The log ID of the newly created log entry
502 */
503 function gamipress_insert_log( $type = '', $user_id = 0, $access = 'public', $trigger_type = '', $log_meta = array() ) {
504
505 global $wpdb;
506
507 // Backward compatibility for functions that called it by the old way
508 if( is_array( $trigger_type ) && empty( $log_meta ) ) {
509 $log_meta = $trigger_type;
510 $trigger_type = '';
511 }
512
513 // Trigger type is not a meta yet, so update it correctly
514 if( isset( $log_meta['trigger_type'] ) ) {
515 $trigger_type = $log_meta['trigger_type'];
516 unset( $log_meta['trigger_type'] );
517 }
518
519 // If not properly upgrade to required version fallback to compatibility function
520 if( ! is_gamipress_upgraded_to( '1.4.7' ) ) {
521
522 $log_meta['trigger_type'] = $trigger_type;
523
524 return gamipress_insert_log_old_147( $type, $user_id, $access, $log_meta );
525 }
526
527 // Setup table
528 $ct_table = ct_setup_table( 'gamipress_logs' );
529
530 // Post data
531 $log_data = array(
532 'title' => '',
533 'type' => $type,
534 'trigger_type' => $trigger_type,
535 'access' => $access,
536 'user_id' => $user_id === 0 ? get_current_user_id() : absint( $user_id ),
537 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
538 );
539
540 if( is_gamipress_upgraded_to( '6.9.4' ) ) {
541 $log_data['points'] = ( isset( $log_meta['points'] ) ) ? $log_meta['points'] : 0;
542 $log_data['points_type'] = ( isset( $log_meta['points_type'] ) ) ? $log_meta['points_type'] : '';
543 }
544
545 // Auto-generated post title
546 $log_data['title'] = gamipress_parse_log_pattern( $log_meta['pattern'], $log_data, $log_meta );
547
548 // Store log entry
549 $log_id = $ct_table->db->insert( $log_data );
550
551 // Store log meta data
552 if ( $log_id && ! empty( $log_meta ) ) {
553
554 $metas = array();
555
556 foreach ( (array) $log_meta as $key => $value ) {
557 // Sanitize vars
558 $meta_key = '_gamipress_' . sanitize_key( $key );
559 $meta_key = wp_unslash( $meta_key );
560 $meta_value = wp_unslash( $value );
561 $meta_value = esc_sql( $meta_value );
562 $meta_value = sanitize_meta( $meta_key, $meta_value, $ct_table->name );
563 $meta_value = maybe_serialize( $meta_value );
564
565 // Setup the insert value
566 $metas[] = $wpdb->prepare( '%d, %s, %s', array( $log_id, $meta_key, $meta_value ) );
567 }
568
569 $logs_meta = GamiPress()->db->logs_meta;
570 $metas = implode( '), (', $metas );
571
572 // Since the log is recently inserted, is faster to run a single query to insert all metas instead of insert them one-by-one
573 $wpdb->query( "INSERT INTO {$logs_meta} (log_id, meta_key, meta_value) VALUES ({$metas})" );
574
575 }
576
577 // Hook to add custom data
578 do_action( 'gamipress_insert_log', $log_id, $log_data, $log_meta, $user_id );
579
580 ct_reset_setup_table();
581
582 return $log_id;
583
584 }
585
586 /**
587 * Parse log pattern replacements
588 *
589 * @since 1.0.0
590 *
591 * @param string $log_pattern The pattern
592 * @param array $log_data Log post data
593 * @param array $log_meta Log meta data
594 *
595 * @return integer The post ID of the newly created log entry
596 */
597 function gamipress_parse_log_pattern( $log_pattern = '', $log_data = array(), $log_meta = array()) {
598
599 // If not properly upgrade to required version fallback to compatibility function
600 if( ! is_gamipress_upgraded_to( '1.2.8' ) ) {
601
602 if( isset( $log_data['user_id'] ) ) {
603 $log_data['post_author'] = $log_data['user_id'];
604 }
605
606 if( isset( $log_data['type'] ) ) {
607 $log_meta['type'] = $log_data['type'];
608 }
609
610 return gamipress_parse_log_pattern_old( $log_pattern, $log_data, $log_meta );
611 }
612
613 global $gamipress_pattern_replacements;
614
615 // Setup site pattern replacements
616 $gamipress_pattern_replacements['{site_title}'] = get_bloginfo( 'name' );
617
618 $user = get_userdata( $log_data['user_id'] );
619
620 // Setup user pattern replacements
621 $gamipress_pattern_replacements['{user_id}'] = ( $user ? $user->ID : '' );
622 $gamipress_pattern_replacements['{user}'] = ( $user ? $user->display_name : '' );
623
624 // TODO: Add more user tags
625
626 $gamipress_pattern_replacements['{trigger_type}'] = gamipress_get_activity_trigger_label( $log_data['trigger_type'] );
627 $gamipress_pattern_replacements['{trigger_type_key}'] = $log_data['trigger_type'];
628
629 foreach( $log_meta as $log_meta_key => $log_meta_value ) {
630
631 if( in_array( $log_meta_key, array( 'pattern', 'type' ) ) )
632 continue;
633
634 // Implode meta value if is an array of values
635 if( is_array( $log_meta_value ) )
636 $log_meta_value = implode( ', ', $log_meta_value );
637
638 $gamipress_pattern_replacements['{' . $log_meta_key . '}'] = $log_meta_value;
639 }
640
641 do_action( 'gamipress_before_parse_log_pattern', $log_data, $log_meta );
642
643 return str_replace( array_keys( $gamipress_pattern_replacements ), $gamipress_pattern_replacements, $log_pattern );
644
645 }
646
647 /**
648 * Log pattern replacements for achievements earn
649 *
650 * @since 1.0.0
651 *
652 * @uses global $gamipress_pattern_replacements
653 *
654 * @param array $log_data Log post data
655 * @param array $log_meta Log meta data
656 */
657 function gamipress_parse_achievement_log_pattern( $log_data, $log_meta ) {
658
659 // If not properly upgrade to required version fallback to compatibility function
660 if( ! is_gamipress_upgraded_to( '1.2.8' ) ) {
661
662 if( isset( $log_data['user_id'] ) ) {
663 $log_data['post_author'] = $log_data['user_id'];
664 }
665
666 if( isset( $log_data['type'] ) ) {
667 $log_meta['type'] = $log_data['type'];
668 }
669
670 gamipress_parse_achievement_log_pattern_old( $log_data, $log_meta );
671 return;
672 }
673
674 // If log has assigned an achievement, then add achievement pattern replacements
675 if( isset( $log_meta['achievement_id'] ) ) {
676
677 global $gamipress_pattern_replacements;
678
679 // Achievement pattern replacements
680 $achievement = gamipress_get_post( $log_meta['achievement_id'] );
681 $achievement_types = gamipress_get_achievement_types();
682 $achievement_type = ( $achievement && isset( $achievement_types[$achievement->post_type]['singular_name'] ) ) ? $achievement_types[$achievement->post_type]['singular_name'] : '';
683
684 // {achievement} tag
685 $gamipress_pattern_replacements['{achievement}'] = $achievement->post_title;
686
687 // {achievement_type} tag
688 $gamipress_pattern_replacements['{achievement_type}'] = $achievement_type;
689
690 if( $log_data['type'] === 'achievement_award' ) {
691 $admin = get_userdata( $log_meta['admin_id'] );
692
693 // {admin_username} tag
694 $gamipress_pattern_replacements['{admin}'] = $admin->display_name;
695 }
696 }
697
698 }
699 add_action( 'gamipress_before_parse_log_pattern', 'gamipress_parse_achievement_log_pattern', 10, 2 );
700
701 /**
702 * Log pattern replacements for points earn/award
703 *
704 * @since 1.0.0
705 *
706 * @uses global $gamipress_pattern_replacements
707 *
708 * @param array $log_data Log post data
709 * @param array $log_meta Log meta data
710 */
711 function gamipress_parse_points_log_pattern( $log_data, $log_meta ) {
712
713 // If not properly upgrade to required version fallback to compatibility function
714 if( ! is_gamipress_upgraded_to( '1.2.8' ) ) {
715
716 if( isset( $log_data['user_id'] ) ) {
717 $log_data['post_author'] = $log_data['user_id'];
718 }
719
720 if( isset( $log_data['type'] ) ) {
721 $log_meta['type'] = $log_data['type'];
722 }
723
724 gamipress_parse_points_log_pattern_old( $log_data, $log_meta );
725 return;
726 }
727
728 // If log is a points based entry, then add points pattern replacements
729 if( $log_data['type'] === 'points_award' || $log_data['type'] === 'points_revoke' || $log_data['type'] === 'points_earn' || $log_data['type'] === 'points_deduct' ) {
730
731 global $gamipress_pattern_replacements;
732
733 // If not properly upgrade to required version fallback to compatibility function
734 if( is_gamipress_upgraded_to( '6.9.4' ) ) {
735 $points = absint( $log_data['points'] );
736 $points_type = $log_data['points_type'];
737 } else {
738 $points = absint( $log_meta['points'] );
739 $points_type = $log_meta['points_type'];
740 }
741
742 $points_types = gamipress_get_points_types();
743
744 // Default points label
745 $points_label = __( 'points', 'gamipress' );
746
747 if( isset( $points_types[$points_type] ) ) {
748 // Points type label
749 $points_label = strtolower( $points_types[$points_type]['plural_name'] );
750 }
751
752 // {points} tag, absint ensures a positive amount to build a pattern like "User expended 100 points" instead of "User expended -100 points"
753 $gamipress_pattern_replacements['{points}'] = gamipress_format_amount( $points, $points_type );
754
755 // {points_type} tag
756 $gamipress_pattern_replacements['{points_type}'] = $points_label;
757
758 if( $log_data['type'] === 'points_award' || $log_data['type'] === 'points_revoke' ) {
759 $admin = get_userdata( $log_meta['admin_id'] );
760
761 // {admin_username} tag
762 $gamipress_pattern_replacements['{admin}'] = $admin->display_name;
763 }
764
765 }
766
767 }
768 add_action( 'gamipress_before_parse_log_pattern', 'gamipress_parse_points_log_pattern', 10, 2 );
769
770 /**
771 * Log pattern replacements for rank earn/award
772 *
773 * @since 1.3.1
774 *
775 * @uses global $gamipress_pattern_replacements
776 *
777 * @param array $log_data Log post data
778 * @param array $log_meta Log meta data
779 */
780 function gamipress_parse_rank_log_pattern( $log_data, $log_meta ) {
781
782 // If log is a points based entry, then add points pattern replacements
783 if( $log_data['type'] === 'rank_award' || $log_data['type'] === 'rank_earn' ) {
784
785 global $gamipress_pattern_replacements;
786
787 $rank = gamipress_get_post( $log_meta['rank_id'] );
788
789 // {rank} and {tank_type} tags
790 $gamipress_pattern_replacements['{rank}'] = $rank ? $rank->post_title : '';
791 $gamipress_pattern_replacements['{rank_type}'] = $rank ? gamipress_get_rank_type_singular( $rank->post_type, true ) : '';
792
793 if( $log_data['type'] === 'rank_award' ) {
794 $admin = get_userdata( $log_meta['admin_id'] );
795
796 // {admin_username} tag
797 $gamipress_pattern_replacements['{admin}'] = $admin->display_name;
798 }
799
800 }
801
802 }
803 add_action( 'gamipress_before_parse_log_pattern', 'gamipress_parse_rank_log_pattern', 10, 2 );
804
805 /**
806 * Update the post title of a log entry.
807 *
808 * @since 1.0.0
809 *
810 * @param array $object_data An array with new object data.
811 * @param array $original_object_data An array with the original object data.
812 * @return array Updated post data.
813 */
814 function gamipress_maybe_apply_log_pattern( $object_data = array(), $original_object_data = array() ) {
815
816 global $ct_table;
817
818 // If not is our logs, return
819 if( $ct_table->name !== 'gamipress_logs' ) {
820 return $object_data;
821 }
822
823 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
824 return $object_data;
825 }
826
827 if ( isset( $original_object_data['log_id'] ) && $original_object_data['log_id'] !== 0 ) {
828
829 $log_id = $original_object_data['log_id'];
830
831 // Just update using pattern if title has been changed
832 if( empty( $object_data['title'] ) ) {
833 // Check pattern
834 if( isset( $_POST['_gamipress_pattern'] ) && ! empty( $_POST['_gamipress_pattern'] ) ) {
835 $pattern = sanitize_text_field( $_POST['_gamipress_pattern'] );
836 } else {
837 $pattern = ct_get_object_meta( $log_id, '_gamipress_pattern', true );
838 }
839
840 // Just parse pattern if not empty
841 if( ! empty( $pattern ) ) {
842 $object_data['title'] = gamipress_get_parsed_log( $log_id );
843 }
844 }
845 }
846
847 return $object_data;
848
849 }
850 add_filter( 'ct_insert_object_data' , 'gamipress_maybe_apply_log_pattern' , 99, 2 );
851
852
853 /**
854 * Get and apply the pattern of a log entry.
855 *
856 * @since 1.0.0
857 *
858 * @param integer $log_id The log's ID.
859 *
860 * @return string Parsed log pattern.
861 */
862 function gamipress_get_parsed_log( $log_id = null ) {
863
864 if( $log_id === null ) {
865 return '';
866 }
867
868 $prefix = '_gamipress_';
869
870 // Setup table
871 ct_setup_table( 'gamipress_logs' );
872
873 $log_data = ct_get_object( $log_id, ARRAY_A );
874
875 if( ! $log_data ) {
876 return '';
877 }
878
879 $log_meta = array(
880 'pattern' => ct_get_object_meta( $log_id, $prefix . 'pattern', true ),
881 );
882
883 $log_meta = apply_filters( 'gamipress_get_log_meta_data', $log_meta, $log_id, $log_data );
884
885 ct_reset_setup_table();
886
887 return gamipress_parse_log_pattern( $log_meta['pattern'], $log_data, $log_meta );
888
889 }
890
891 /**
892 * Get log meta data defaults from a log's object ID
893 *
894 * @param $log_meta
895 * @param $log_id
896 * @param $log_data
897 *
898 * @return mixed
899 */
900 function gamipress_get_log_meta_data_defaults( $log_meta, $log_id, $log_data ) {
901
902 $prefix = '_gamipress_';
903
904 $meta_keys = array();
905
906 if( $log_data['type'] === 'event_trigger' ) {
907 // Event trigger meta data
908
909 // If not upgraded to 1.4.7 yet, return trigger_type as a meta data
910 if( ! is_gamipress_upgraded_to( '1.4.7' ) ) {
911 $meta_keys[] = 'trigger_type';
912 }
913
914 $meta_keys[] = 'count';
915 } else if( $log_data['type'] === 'achievement_earn' || $log_data['type'] === 'achievement_award' ) {
916 // Achievement earn meta data
917 $meta_keys[] = 'achievement_id';
918
919 if( $log_data['type'] === 'achievement_award' ) {
920 // Specific achievement award meta data
921 $meta_keys[] = 'admin_id';
922 }
923 } else if( $log_data['type'] === 'points_award' || $log_data['type'] === 'points_revoke' || $log_data['type'] === 'points_earn' || $log_data['type'] === 'points_deduct' ) {
924 // Points earn/deduct/award/revoke meta data
925 $meta_keys[] = 'points';
926 $meta_keys[] = 'points_type';
927 $meta_keys[] = 'total_points';
928
929 if( $log_data['type'] === 'points_award' || $log_data['type'] === 'points_revoke' ) {
930 // Specific points award meta data
931 $meta_keys[] = 'admin_id';
932 }
933 } else if( $log_data['type'] === 'rank_earn' || $log_data['type'] === 'rank_award' ) {
934 // Achievement earn meta data
935 $meta_keys[] = 'rank_id';
936
937 if( $log_data['type'] === 'rank_award' ) {
938 // Specific rank award meta data
939 $meta_keys[] = 'admin_id';
940 }
941 }
942
943 foreach( $meta_keys as $meta_key ) {
944 $log_meta[$meta_key] = ct_get_object_meta( $log_id, $prefix . $meta_key, true );
945 }
946
947 return $log_meta;
948
949 }
950 add_filter( 'gamipress_get_log_meta_data', 'gamipress_get_log_meta_data_defaults', 10, 3 );
951
952 /**
953 * Get the log object data
954 *
955 * @since 2.1.2
956 *
957 * @param int $log_id The log ID
958 * @param string $meta_key The meta key to retrieve. By default, returns
959 * data for all keys. Default empty.
960 * @param bool $single Optional. Whether to return a single value. Default false.
961 *
962 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
963 */
964 function gamipress_get_log_meta( $log_id, $meta_key = '', $single = false ) {
965
966 ct_setup_table( 'gamipress_logs' );
967
968 $meta_value = ct_get_object_meta( $log_id, $meta_key, $single );
969
970 ct_reset_setup_table();
971
972 return $meta_value;
973
974 }
975
976 /**
977 * Update the log object data
978 *
979 * @since 2.1.2
980 *
981 * @param int $log_id The log ID
982 * @param string $meta_key Metadata key.
983 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
984 * @param mixed $prev_value Optional. Previous value to check before removing.
985 * Default empty.
986 *
987 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
988 */
989 function gamipress_update_log_meta( $log_id, $meta_key, $meta_value, $prev_value = '' ) {
990
991 ct_setup_table( 'gamipress_logs' );
992
993 $meta_id = ct_update_object_meta( $log_id, $meta_key, $meta_value, $prev_value );
994
995 ct_reset_setup_table();
996
997 return $meta_id;
998
999 }
1000