Completed
Push — master ( cbdcdc...d800f4 )
by Devin
39:33 queued 19:39
created

Give_Logging::get_log_count()   C

Complexity

Conditions 7
Paths 32

Size

Total Lines 45
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 7.116

Importance

Changes 0
Metric Value
cc 7
eloc 24
nc 32
nop 4
dl 0
loc 45
ccs 13
cts 15
cp 0.8667
crap 7.116
rs 6.7272
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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 6
	 * @since  1.0
32
	 * @access public
33 6
	 */
34
	public function __construct() {
35
	}
36 6
37
38 6
	/**
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 6
48
		// Create types taxonomy and default types
49
		add_action( 'init', array( $this, 'register_taxonomy' ), 1 );
50 6
51 6
		add_action( 'save_post_give_payment', array( $this, 'background_process_delete_cache' ) );
52 6
		add_action( 'save_post_give_forms', array( $this, 'background_process_delete_cache' ) );
53 6
		add_action( 'save_post_give_log', array( $this, 'background_process_delete_cache' ) );
54 6
		add_action( 'give_delete_log_cache', array( $this, 'delete_cache' ) );
55 6
	}
56 6
57 6
	/**
58 6
	 * Log Post Type
59
	 *
60 6
	 * Registers the 'give_log' Post Type.
61
	 *
62 6
	 * @since  1.0
63 6
	 * @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 6
			'exclude_from_search' => true,
75 6
			'publicly_queryable'  => false,
76 6
			'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 55
	/**
88
	 * Log Type Taxonomy
89 55
	 *
90 55
	 * Registers the "Log Type" taxonomy.  Used to determine the type of log entry.
91
	 *
92 55
	 * @since  1.0
93
	 * @access public
94 55
	 *
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 54
	 *
111 54
	 * @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 1
	 * @param  string $type Log type.
132
	 *
133 1
	 * @return bool         Whether log type is valid.
134 1
	 */
135 1
	public function valid_type( $type ) {
136
		return in_array( $type, $this->log_types() );
137 1
	}
138
139 1
	/**
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 1
	public function add( $title = '', $message = '', $parent = 0, $type = null ) {
156 1
		$log_data = array(
157 1
			'post_title'   => $title,
158 1
			'post_content' => $message,
159
			'post_parent'  => $parent,
160 1
			'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 43
	 * @param  string $type      Log type. Default is null.
176
	 * @param  int    $paged     Page number Default is null.
177 43
	 *
178 43
	 * @return array             An array of the connected logs.
0 ignored issues
show
Documentation introduced by
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 43
	 */
180 43
	public function get_logs( $object_id = 0, $type = null, $paged = null ) {
181
		return $this->get_connected_logs( array(
182 43
			'post_parent' => $object_id,
183
			'paged'       => $paged,
184 43
			'log_type'    => $type,
185
		) );
186 43
	}
187
188
	/**
189 43
	 * Stores a log entry
190
	 *
191
	 * @since  1.0
192 43
	 * @access public
193 43
	 *
194 43
	 * @param  array $log_data Log entry data.
195
	 * @param  array $log_meta Log entry meta.
196
	 *
197 43
	 * @return int             The ID of the newly created log item.
198 42
	 */
199 42
	public function insert_log( $log_data = array(), $log_meta = array() ) {
200 42
		$defaults = array(
201 42
			'post_type'    => 'give_log',
202
			'post_status'  => 'publish',
203 43
			'post_parent'  => 0,
204
			'post_content' => '',
205 43
			'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 1
	 *
258
	 * @return bool|null       True if successful, false otherwise.
259
	 */
260 1
	public function update_log( $log_data = array(), $log_meta = array() ) {
261 1
262 1
		/**
263 1
		 * Fires before updating log entry.
264
		 *
265 1
		 * @since 1.0
266
		 *
267 1
		 * @param array $log_data Log entry data.
268
		 * @param array $log_meta Log entry meta.
269 1
		 */
270 1
		do_action( 'give_pre_update_log', $log_data, $log_meta );
271
272 1
		$defaults = array(
273 1
			'post_type'   => 'give_log',
274 1
			'post_status' => 'publish',
275 1
			'post_parent' => 0,
276 1
		);
277 1
278
		$args = wp_parse_args( $log_data, $defaults );
279 1
280
		// Store the log entry
281 1
		$log_id = wp_update_post( $args );
282 1
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 1
303
	/**
304
	 * Retrieve all connected logs
305 1
	 *
306 1
	 * Used for retrieving logs related to particular items, such as a specific donation.
307 1
	 *
308 1
	 * @since  1.0
309 1
	 * @access public
310 1
	 *
311
	 * @param  array $args Query arguments.
312 1
	 *
313 1
	 * @return array|false Array if logs were found, false otherwise.
314
	 */
315 1
	public function get_connected_logs( $args = array() ) {
316 1
317
		$defaults = array(
318 1
			'post_type'      => 'give_log',
319 1
			'posts_per_page' => 20,
320 1
			'post_status'    => 'publish',
321
			'paged'          => get_query_var( 'paged' ),
322 1
			'log_type'       => false,
323
		);
324
325
		$query_args = wp_parse_args( $args, $defaults );
326 1
327
		if ( $query_args['log_type'] && $this->valid_type( $query_args['log_type'] ) ) {
328
			$query_args['tax_query'] = array(
329
				array(
330 1
					'taxonomy' => 'give_log_type',
331
					'field'    => 'slug',
332 1
					'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 32
	 * Retrieve Log Count
349
	 *
350 32
	 * Retrieves number of log entries connected to particular object ID.
351 32
	 *
352 32
	 * @since  1.0
353 32
	 * @access public
354
	 *
355 32
	 * @param  int    $object_id  Log object ID. Default is 0.
356
	 * @param  string $type       Log type. Default is null.
357 32
	 * @param  array  $meta_query Log meta query. Default is null.
358 31
	 * @param  array  $date_query Log data query. Default is null.
359
	 *
360 31
	 * @return int                Log count.
361 31
	 */
362 31
	public function get_log_count( $object_id = 0, $type = null, $meta_query = null, $date_query = null ) {
363
364 31
		$query_args = array(
365 31
			'post_type'      => 'give_log',
366
			'posts_per_page' => - 1,
367 32
			'post_status'    => 'publish',
368 31
			'fields'         => 'ids',
369 31
		);
370
371 32
		if ( $object_id ) {
372
			$query_args['post_parent'] = $object_id;
373 32
		}
374 7
375 7
		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
376 7
			$query_args['tax_query'] = array(
377 7
				array(
378 32
					'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 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $post_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
Documentation introduced by
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;
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...
517
	$log = $give_logs->add( $title, $message, $parent, $type );
518
519
	return $log;
520
}
521