Completed
Push — issues/1617 ( faec36 )
by Ravinder
20:40
created

Give_Logging::delete_cache()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 3
nop 0
dl 0
loc 26
rs 8.8571
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
	 * @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
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
	 */
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 );
0 ignored issues
show
Deprecated Code introduced by
The function give_get_cache_key() has been deprecated with message: 1.8.7 You can access this function from Give_Cache.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
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
		// Delete log cache immediately
464
		wp_schedule_single_event( time() - 5, 'give_delete_log_cache' );
465
	}
466
467
	/**
468
	 * Delete all logging cache when form, log or payment updates
469
	 *
470
	 * @since  1.7
471
	 * @access public
472
	 *
473
	 * @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...
474
	 */
475
	public function delete_cache() {
476
		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...
477
478
		// Add log related keys to delete.
479
		$cache_option_names = $wpdb->get_results(
480
			$wpdb->prepare(
481
				"SELECT option_name
482
						FROM {$wpdb->options}
483
						where option_name LIKE '%%%s%%'
484
						OR option_name LIKE '%%%s%%'",
485
				'give_cache_get_logs',
486
				'give_cache_get_log_count'
487
			),
488
			ARRAY_A
489
		);
490
491
		// Bailout.
492
		if ( empty( $cache_option_names ) ) {
493
			return false;
494
		}
495
496
		// Delete log cache.
497
		foreach ( $cache_option_names as $option_name ) {
498
			delete_option( $option_name['option_name'] );
499
		}
500
	}
501
}
502
503
// Initiate the logging system
504
$GLOBALS['give_logs'] = new Give_Logging();
505
$GLOBALS['give_logs']->__setup_hooks();
506
507
/**
508
 * Record a log entry
509
 *
510
 * A wrapper function for the Give_Logging class add() method.
511
 *
512
 * @since  1.0
513
 *
514
 * @param  string $title   Log title. Default is empty.
515
 * @param  string $message Log message. Default is empty.
516
 * @param  int    $parent  Parent log. Default is 0.
517
 * @param  string $type    Log type. Default is null.
518
 *
519
 * @return int             ID of the new log entry.
520
 */
521
function give_record_log( $title = '', $message = '', $parent = 0, $type = null ) {
522
	/* @var Give_Logging $give_logs */
523
	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...
524
	$log = $give_logs->add( $title, $message, $parent, $type );
525
526
	return $log;
527
}
528