Completed
Push — issues/611 ( 661115...758b1c )
by Ravinder
21:11
created

includes/class-give-logging.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Class for logging events and errors
4
 *
5
 * @package     Give
6
 * @subpackage  Classes/Give_Logging
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Give_Logging Class
19
 *
20
 * A general use class for logging events and errors.
21
 *
22
 * @since 1.0
23
 */
24
class Give_Logging {
25
26
	/**
27
	 * Class Constructor
28
	 *
29
	 * Set up the Give Logging Class.
30
	 *
31
	 * @since  1.0
32
	 * @access public
33
	 */
34
	public function __construct() {
35
	}
36
37
38
	/**
39
	 * Setup hooks
40
	 *
41
	 * @since  1.7
42
	 * @access public
43
	 */
44
	public function __setup_hooks() {
45
		// Create the log post type
46
		add_action( 'init', array( $this, 'register_post_type' ), 1 );
47
48
		// Create types taxonomy and default types
49
		add_action( 'init', array( $this, 'register_taxonomy' ), 1 );
50
51
		add_action( 'save_post_give_payment', array( $this, 'background_process_delete_cache' ) );
52
		add_action( 'save_post_give_forms', array( $this, 'background_process_delete_cache' ) );
53
		add_action( 'save_post_give_log', array( $this, 'background_process_delete_cache' ) );
54
		add_action( 'give_delete_log_cache', array( $this, 'delete_cache' ) );
55
	}
56
57
	/**
58
	 * Log Post Type
59
	 *
60
	 * Registers the 'give_log' Post Type.
61
	 *
62
	 * @since  1.0
63
	 * @access public
64
	 *
65
	 * @return void
66
	 */
67
	public function register_post_type() {
68
		/* Logs post type */
69
		$log_args = array(
70
			'labels'              => array(
71
				'name' => esc_html__( 'Logs', 'give' ),
72
			),
73
			'public'              => false,
74
			'exclude_from_search' => true,
75
			'publicly_queryable'  => false,
76
			'show_ui'             => false,
77
			'query_var'           => false,
78
			'rewrite'             => false,
79
			'capability_type'     => 'post',
80
			'supports'            => array( 'title', 'editor' ),
81
			'can_export'          => true,
82
		);
83
84
		register_post_type( 'give_log', $log_args );
85
	}
86
87
	/**
88
	 * Log Type Taxonomy
89
	 *
90
	 * Registers the "Log Type" taxonomy.  Used to determine the type of log entry.
91
	 *
92
	 * @since  1.0
93
	 * @access public
94
	 *
95
	 * @return void
96
	 */
97
	public function register_taxonomy() {
98
		register_taxonomy( 'give_log_type', 'give_log', array(
99
			'public' => false,
100
		) );
101
	}
102
103
	/**
104
	 * Log Types
105
	 *
106
	 * Sets up the default log types and allows for new ones to be created.
107
	 *
108
	 * @since  1.0
109
	 * @access public
110
	 *
111
	 * @return array $terms
112
	 */
113
	public function log_types() {
114
		$terms = array(
115
			'sale',
116
			'gateway_error',
117
			'api_request',
118
		);
119
120
		return apply_filters( 'give_log_types', $terms );
121
	}
122
123
	/**
124
	 * Check if a log type is valid
125
	 *
126
	 * Checks to see if the specified type is in the registered list of types.
127
	 *
128
	 * @since  1.0
129
	 * @access public
130
	 *
131
	 * @param  string $type Log type.
132
	 *
133
	 * @return bool         Whether log type is valid.
134
	 */
135
	public function valid_type( $type ) {
136
		return in_array( $type, $this->log_types() );
137
	}
138
139
	/**
140
	 * Create new log entry
141
	 *
142
	 * This is just a simple and fast way to log something. Use $this->insert_log()
143
	 * if you need to store custom meta data.
144
	 *
145
	 * @since  1.0
146
	 * @access public
147
	 *
148
	 * @param  string $title   Log entry title. Default is empty.
149
	 * @param  string $message Log entry message. Default is empty.
150
	 * @param  int    $parent  Log entry parent. Default is 0.
151
	 * @param  string $type    Log type. Default is null.
152
	 *
153
	 * @return int             Log ID.
154
	 */
155
	public function add( $title = '', $message = '', $parent = 0, $type = null ) {
156
		$log_data = array(
157
			'post_title'   => $title,
158
			'post_content' => $message,
159
			'post_parent'  => $parent,
160
			'log_type'     => $type,
161
		);
162
163
		return $this->insert_log( $log_data );
164
	}
165
166
	/**
167
	 * Get Logs
168
	 *
169
	 * Retrieves log items for a particular object ID.
170
	 *
171
	 * @since  1.0
172
	 * @access public
173
	 *
174
	 * @param  int    $object_id Log object ID. Default is 0.
175
	 * @param  string $type      Log type. Default is null.
176
	 * @param  int    $paged     Page number Default is null.
177
	 *
178
	 * @return array             An array of the connected logs.
0 ignored issues
show
Should the return type not be array|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
179
	 */
180
	public function get_logs( $object_id = 0, $type = null, $paged = null ) {
181
		return $this->get_connected_logs( array(
182
			'post_parent' => $object_id,
183
			'paged'       => $paged,
184
			'log_type'    => $type,
185
		) );
186
	}
187
188
	/**
189
	 * Stores a log entry
190
	 *
191
	 * @since  1.0
192
	 * @access public
193
	 *
194
	 * @param  array $log_data Log entry data.
195
	 * @param  array $log_meta Log entry meta.
196
	 *
197
	 * @return int             The ID of the newly created log item.
198
	 */
199
	public function insert_log( $log_data = array(), $log_meta = array() ) {
200
		$defaults = array(
201
			'post_type'    => 'give_log',
202
			'post_status'  => 'publish',
203
			'post_parent'  => 0,
204
			'post_content' => '',
205
			'log_type'     => false,
206
		);
207
208
		$args = wp_parse_args( $log_data, $defaults );
209
210
		/**
211
		 * Fires before inserting log entry.
212
		 *
213
		 * @since 1.0
214
		 *
215
		 * @param array $log_data Log entry data.
216
		 * @param array $log_meta Log entry meta.
217
		 */
218
		do_action( 'give_pre_insert_log', $log_data, $log_meta );
219
220
		// Store the log entry
221
		$log_id = wp_insert_post( $args );
222
223
		// Set the log type, if any
224
		if ( $log_data['log_type'] && $this->valid_type( $log_data['log_type'] ) ) {
225
			wp_set_object_terms( $log_id, $log_data['log_type'], 'give_log_type', false );
226
		}
227
228
		// Set log meta, if any
229
		if ( $log_id && ! empty( $log_meta ) ) {
230
			foreach ( (array) $log_meta as $key => $meta ) {
231
				update_post_meta( $log_id, '_give_log_' . sanitize_key( $key ), $meta );
232
			}
233
		}
234
235
		/**
236
		 * Fires after inserting log entry.
237
		 *
238
		 * @since 1.0
239
		 *
240
		 * @param int   $log_id   Log entry id.
241
		 * @param array $log_data Log entry data.
242
		 * @param array $log_meta Log entry meta.
243
		 */
244
		do_action( 'give_post_insert_log', $log_id, $log_data, $log_meta );
245
246
		return $log_id;
247
	}
248
249
	/**
250
	 * Update and existing log item
251
	 *
252
	 * @since  1.0
253
	 * @access public
254
	 *
255
	 * @param  array $log_data Log entry data.
256
	 * @param  array $log_meta Log entry meta.
257
	 *
258
	 * @return bool|null       True if successful, false otherwise.
259
	 */
260
	public function update_log( $log_data = array(), $log_meta = array() ) {
261
262
		/**
263
		 * Fires before updating log entry.
264
		 *
265
		 * @since 1.0
266
		 *
267
		 * @param array $log_data Log entry data.
268
		 * @param array $log_meta Log entry meta.
269
		 */
270
		do_action( 'give_pre_update_log', $log_data, $log_meta );
271
272
		$defaults = array(
273
			'post_type'   => 'give_log',
274
			'post_status' => 'publish',
275
			'post_parent' => 0,
276
		);
277
278
		$args = wp_parse_args( $log_data, $defaults );
279
280
		// Store the log entry
281
		$log_id = wp_update_post( $args );
282
283
		if ( $log_id && ! empty( $log_meta ) ) {
284
			foreach ( (array) $log_meta as $key => $meta ) {
285
				if ( ! empty( $meta ) ) {
286
					update_post_meta( $log_id, '_give_log_' . sanitize_key( $key ), $meta );
287
				}
288
			}
289
		}
290
291
		/**
292
		 * Fires after updating log entry.
293
		 *
294
		 * @since 1.0
295
		 *
296
		 * @param int   $log_id   Log entry id.
297
		 * @param array $log_data Log entry data.
298
		 * @param array $log_meta Log entry meta.
299
		 */
300
		do_action( 'give_post_update_log', $log_id, $log_data, $log_meta );
301
	}
302
303
	/**
304
	 * Retrieve all connected logs
305
	 *
306
	 * Used for retrieving logs related to particular items, such as a specific donation.
307
	 *
308
	 * @since  1.0
309
	 * @access public
310
	 *
311
	 * @param  array $args Query arguments.
312
	 *
313
	 * @return array|false Array if logs were found, false otherwise.
314
	 */
315
	public function get_connected_logs( $args = array() ) {
316
317
		$defaults = array(
318
			'post_type'      => 'give_log',
319
			'posts_per_page' => 20,
320
			'post_status'    => 'publish',
321
			'paged'          => get_query_var( 'paged' ),
322
			'log_type'       => false,
323
		);
324
325
		$query_args = wp_parse_args( $args, $defaults );
326
327
		if ( $query_args['log_type'] && $this->valid_type( $query_args['log_type'] ) ) {
328
			$query_args['tax_query'] = array(
329
				array(
330
					'taxonomy' => 'give_log_type',
331
					'field'    => 'slug',
332
					'terms'    => $query_args['log_type'],
333
				),
334
			);
335
		}
336
337
		$logs = get_posts( $query_args );
338
339
		if ( $logs ) {
340
			return $logs;
341
		}
342
343
		// No logs found
344
		return false;
345
	}
346
347
	/**
348
	 * Retrieve Log Count
349
	 *
350
	 * Retrieves number of log entries connected to particular object ID.
351
	 *
352
	 * @since  1.0
353
	 * @access public
354
	 *
355
	 * @param  int    $object_id  Log object ID. Default is 0.
356
	 * @param  string $type       Log type. Default is null.
357
	 * @param  array  $meta_query Log meta query. Default is null.
358
	 * @param  array  $date_query Log data query. Default is null.
359
	 *
360
	 * @return int                Log count.
361
	 */
362
	public function get_log_count( $object_id = 0, $type = null, $meta_query = null, $date_query = null ) {
363
364
		$query_args = array(
365
			'post_type'      => 'give_log',
366
			'posts_per_page' => - 1,
367
			'post_status'    => 'publish',
368
			'fields'         => 'ids',
369
		);
370
371
		if ( $object_id ) {
372
			$query_args['post_parent'] = $object_id;
373
		}
374
375
		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
376
			$query_args['tax_query'] = array(
377
				array(
378
					'taxonomy' => 'give_log_type',
379
					'field'    => 'slug',
380
					'terms'    => $type,
381
				),
382
			);
383
		}
384
385
		if ( ! empty( $meta_query ) ) {
386
			$query_args['meta_query'] = $meta_query;
387
		}
388
389
		if ( ! empty( $date_query ) ) {
390
			$query_args['date_query'] = $date_query;
391
		}
392
393
		// Get cache key for current query.
394
		$cache_key = give_get_cache_key( 'get_log_count', $query_args );
395
396
		// check if cache already exist or not.
397
		if ( ! ( $logs_count = get_option( $cache_key ) ) ) {
398
			$logs       = new WP_Query( $query_args );
399
			$logs_count = (int) $logs->post_count;
400
401
			// Cache results.
402
			add_option( $cache_key, $logs_count, '', 'no' );
403
		}
404
405
		return $logs_count;
406
	}
407
408
	/**
409
	 * Delete Logs
410
	 *
411
	 * Remove log entries connected to particular object ID.
412
	 *
413
	 * @since  1.0
414
	 * @access public
415
	 *
416
	 * @param  int    $object_id  Log object ID. Default is 0.
417
	 * @param  string $type       Log type. Default is null.
418
	 * @param  array  $meta_query Log meta query. Default is null.
419
	 *
420
	 * @return void
421
	 */
422
	public function delete_logs( $object_id = 0, $type = null, $meta_query = null ) {
423
		$query_args = array(
424
			'post_parent'    => $object_id,
425
			'post_type'      => 'give_log',
426
			'posts_per_page' => - 1,
427
			'post_status'    => 'publish',
428
			'fields'         => 'ids',
429
		);
430
431
		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
432
			$query_args['tax_query'] = array(
433
				array(
434
					'taxonomy' => 'give_log_type',
435
					'field'    => 'slug',
436
					'terms'    => $type,
437
				),
438
			);
439
		}
440
441
		if ( ! empty( $meta_query ) ) {
442
			$query_args['meta_query'] = $meta_query;
443
		}
444
445
		$logs = get_posts( $query_args );
446
447
		if ( $logs ) {
448
			foreach ( $logs as $log ) {
449
				wp_delete_post( $log, true );
450
			}
451
		}
452
	}
453
454
	/**
455
	 * Setup cron to delete log cache in background.
456
	 *
457
	 * @since  1.7
458
	 * @access public
459
	 *
460
	 * @param int $post_id
461
	 */
462
	public function background_process_delete_cache( $post_id ) {
463
		wp_schedule_single_event( time(), 'give_delete_log_cache' );
464
	}
465
466
	/**
467
	 * Delete all logging cache when form, log or payment updates
468
	 *
469
	 * @since  1.7
470
	 * @access public
471
	 *
472
	 * @return bool
0 ignored issues
show
Should the return type not be false|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
473
	 */
474
	public function delete_cache() {
475
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
476
		$cache_option_names = $wpdb->get_results(
477
			$wpdb->prepare(
478
				"SELECT option_name FROM {$wpdb->options} where option_name LIKE '%%%s%%'",
479
				'give_cache'
480
			),
481
			ARRAY_A
482
		);
483
484
		// Bailout.
485
		if ( empty( $cache_option_names ) ) {
486
			return false;
487
		}
488
489
		// Delete log cache.
490
		foreach ( $cache_option_names as $option_name ) {
491
			delete_option( $option_name['option_name'] );
492
		}
493
	}
494
}
495
496
// Initiate the logging system
497
$GLOBALS['give_logs'] = new Give_Logging();
498
$GLOBALS['give_logs']->__setup_hooks();
499
500
/**
501
 * Record a log entry
502
 *
503
 * A wrapper function for the Give_Logging class add() method.
504
 *
505
 * @since  1.0
506
 *
507
 * @param  string $title   Log title. Default is empty.
508
 * @param  string $message Log message. Default is empty.
509
 * @param  int    $parent  Parent log. Default is 0.
510
 * @param  string $type    Log type. Default is null.
511
 *
512
 * @return int             ID of the new log entry.
513
 */
514
function give_record_log( $title = '', $message = '', $parent = 0, $type = null ) {
515
	/* @var Give_Logging $give_logs */
516
	global $give_logs;
517
	$log = $give_logs->add( $title, $message, $parent, $type );
518
519
	return $log;
520
}
521