Completed
Push — issues/1796 ( fe0f55...71eafd )
by Ravinder
17:33
created

Give_Logging::get_log_count()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 4
dl 0
loc 18
rs 9.4285
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
	 * Logs data operation handler object.
27
	 *
28
	 * @since  2.0
29
	 * @access private
30
	 * @var Give_DB_Logs
31
	 */
32
	public $log_db;
33
34
	/**
35
	 * Log meta data operation handler object.
36
	 *
37
	 * @since  2.0
38
	 * @access private
39
	 * @var Give_DB_Log_Meta
40
	 */
41
	public $logmeta_db;
42
43
	/**
44
	 * Class Constructor
45
	 *
46
	 * Set up the Give Logging Class.
47
	 *
48
	 * @since  1.0
49
	 * @access public
50
	 */
51
	public function __construct() {
52
		require_once GIVE_PLUGIN_DIR . 'includes/class-give-db-logs.php';
53
		require_once GIVE_PLUGIN_DIR . 'includes/class-give-db-logs-meta.php';
54
		$this->log_db     = new Give_DB_Logs();
55
		$this->logmeta_db = new Give_DB_Log_Meta();
56
57
58
		add_action( 'save_post_give_payment', array( $this, 'background_process_delete_cache' ) );
59
		add_action( 'save_post_give_forms', array( $this, 'background_process_delete_cache' ) );
60
		add_action( 'save_post_give_log', array( $this, 'background_process_delete_cache' ) );
61
		add_action( 'give_delete_log_cache', array( $this, 'delete_cache' ) );
62
63
		// Create the log post type
64
		add_action( 'init', array( $this, 'register_post_type' ), 1 );
65
66
		// Create types taxonomy and default types
67
		add_action( 'init', array( $this, 'register_taxonomy' ), 1 );
68
	}
69
70
71
	/**
72
	 * Log Post Type
73
	 *
74
	 * Registers the 'give_log' Post Type.
75
	 *
76
	 * @since  1.0
77
	 * @access public
78
	 *
79
	 * @return void
80
	 */
81
	public function register_post_type() {
82
		/* Logs post type */
83
		$log_args = array(
84
			'labels'              => array(
85
				'name' => esc_html__( 'Logs', 'give' ),
86
			),
87
			'public'              => false,
88
			'exclude_from_search' => true,
89
			'publicly_queryable'  => false,
90
			'show_ui'             => false,
91
			'query_var'           => false,
92
			'rewrite'             => false,
93
			'capability_type'     => 'post',
94
			'supports'            => array( 'title', 'editor' ),
95
			'can_export'          => true,
96
		);
97
98
		register_post_type( 'give_log', $log_args );
99
	}
100
101
	/**
102
	 * Log Type Taxonomy
103
	 *
104
	 * Registers the "Log Type" taxonomy.  Used to determine the type of log entry.
105
	 *
106
	 * @since  1.0
107
	 * @access public
108
	 *
109
	 * @return void
110
	 */
111
	public function register_taxonomy() {
112
		register_taxonomy( 'give_log_type', 'give_log', array(
113
			'public' => false,
114
		) );
115
	}
116
117
	/**
118
	 * Log Types
119
	 *
120
	 * Sets up the default log types and allows for new ones to be created.
121
	 *
122
	 * @since  1.0
123
	 * @access public
124
	 *
125
	 * @return array $terms
126
	 */
127
	public function log_types() {
128
		$terms = array(
129
			'sale',
130
			'gateway_error',
131
			'api_request',
132
		);
133
134
		return apply_filters( 'give_log_types', $terms );
135
	}
136
137
	/**
138
	 * Check if a log type is valid
139
	 *
140
	 * Checks to see if the specified type is in the registered list of types.
141
	 *
142
	 * @since  1.0
143
	 * @access public
144
	 *
145
	 * @param  string $type Log type.
146
	 *
147
	 * @return bool         Whether log type is valid.
148
	 */
149
	public function valid_type( $type ) {
150
		return in_array( $type, $this->log_types() );
151
	}
152
153
	/**
154
	 * Create new log entry
155
	 *
156
	 * This is just a simple and fast way to log something. Use $this->insert_log()
157
	 * if you need to store custom meta data.
158
	 *
159
	 * @since  1.0
160
	 * @access public
161
	 *
162
	 * @param  string $title   Log entry title. Default is empty.
163
	 * @param  string $message Log entry message. Default is empty.
164
	 * @param  int    $parent  Log entry parent. Default is 0.
165
	 * @param  string $type    Log type. Default is null.
166
	 *
167
	 * @return int             Log ID.
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer?

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...
168
	 */
169
	public function add( $title = '', $message = '', $parent = 0, $type = null ) {
170
		// @todo: add backward compatibility for old table.
171
		$log_data = array(
172
			'title'   => $title,
173
			'content' => $message,
174
			'parent'  => $parent,
175
			'type'    => $type,
176
		);
177
178
		return $this->log_db->add( $log_data );
179
	}
180
181
	/**
182
	 * Get Logs
183
	 *
184
	 * Retrieves log items for a particular object ID.
185
	 *
186
	 * @since  1.0
187
	 * @access public
188
	 *
189
	 * @param  int    $object_id Log object ID. Default is 0.
190
	 * @param  string $type      Log type. Default is null.
191
	 * @param  int    $paged     Page number Default is null.
192
	 *
193
	 * @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...
194
	 */
195
	public function get_logs( $object_id = 0, $type = null, $paged = null ) {
196
		// @todo: add backward compatibility for old table.
197
		return $this->get_connected_logs( array(
198
			'parent' => $object_id,
199
			'type'   => $type,
200
			'paged'  => $paged,
201
		) );
202
	}
203
204
	/**
205
	 * Stores a log entry
206
	 *
207
	 * @since  1.0
208
	 * @access public
209
	 *
210
	 * @param  array $log_data Log entry data.
211
	 * @param  array $log_meta Log entry meta.
212
	 *
213
	 * @return int             The ID of the newly created log item.
214
	 */
215
	public function insert_log( $log_data = array(), $log_meta = array() ) {
216
		// @todo: add backward compatibility for old table.
217
218
		/**
219
		 * Fires before inserting log entry.
220
		 *
221
		 * @since 1.0
222
		 *
223
		 * @param array $log_data Log entry data.
224
		 * @param array $log_meta Log entry meta.
225
		 */
226
		do_action( 'give_pre_insert_log', $log_data, $log_meta );
227
228
		// Store the log entry
229
		$log_id = $this->log_db->insert( $log_data );
230
231
		// Set log meta, if any
232
		if ( $log_id && ! empty( $log_meta ) ) {
233
			foreach ( (array) $log_meta as $key => $meta ) {
234
				$this->logmeta_db->update_meta( $log_id, sanitize_key( $key ), $meta );
235
			}
236
		}
237
238
		/**
239
		 * Fires after inserting log entry.
240
		 *
241
		 * @since 1.0
242
		 *
243
		 * @param int   $log_id   Log entry id.
244
		 * @param array $log_data Log entry data.
245
		 * @param array $log_meta Log entry meta.
246
		 */
247
		do_action( 'give_post_insert_log', $log_id, $log_data, $log_meta );
248
249
		return $log_id;
250
	}
251
252
	/**
253
	 * Update and existing log item
254
	 *
255
	 * @since  1.0
256
	 * @access public
257
	 *
258
	 * @param  array $log_data Log entry data.
259
	 * @param  array $log_meta Log entry meta.
260
	 *
261
	 * @return bool|null       True if successful, false otherwise.
262
	 */
263
	public function update_log( $log_data = array(), $log_meta = array() ) {
264
265
		/**
266
		 * Fires before updating log entry.
267
		 *
268
		 * @since 1.0
269
		 *
270
		 * @param array $log_data Log entry data.
271
		 * @param array $log_meta Log entry meta.
272
		 */
273
		do_action( 'give_pre_update_log', $log_data, $log_meta );
274
275
		$defaults = array(
276
			'post_type'   => 'give_log',
277
			'post_status' => 'publish',
278
			'post_parent' => 0,
279
		);
280
281
		$args = wp_parse_args( $log_data, $defaults );
282
283
		// Store the log entry
284
		$log_id = wp_update_post( $args );
285
286
		if ( $log_id && ! empty( $log_meta ) ) {
287
			foreach ( (array) $log_meta as $key => $meta ) {
288
				if ( ! empty( $meta ) ) {
289
					give_update_meta( $log_id, '_give_log_' . sanitize_key( $key ), $meta );
290
				}
291
			}
292
		}
293
294
		/**
295
		 * Fires after updating log entry.
296
		 *
297
		 * @since 1.0
298
		 *
299
		 * @param int   $log_id   Log entry id.
300
		 * @param array $log_data Log entry data.
301
		 * @param array $log_meta Log entry meta.
302
		 */
303
		do_action( 'give_post_update_log', $log_id, $log_data, $log_meta );
304
	}
305
306
	/**
307
	 * Retrieve all connected logs
308
	 *
309
	 * Used for retrieving logs related to particular items, such as a specific donation.
310
	 *
311
	 * @since  1.0
312
	 * @access public
313
	 *
314
	 * @param  array $args Query arguments.
315
	 *
316
	 * @return array|false Array if logs were found, false otherwise.
317
	 */
318
	public function get_connected_logs( $args = array() ) {
319
		// @todo: add backward compatibility for old table.
320
		$defaults = array(
321
			'number' => 20,
322
			'paged'  => get_query_var( 'paged' ),
323
			'type'   => false,
324
			'date'   => null,
325
		);
326
327
		$query_args = wp_parse_args( $args, $defaults );
328
329
		// Retrieve logs based on specific timeframe
330
		if ( ! empty ( $query_args['date'] ) && is_array( $query_args['date'] ) ) {
331
			if ( ! empty( $query_args['date']['start'] ) ) {
332
				$query_args['date']['after'] = array(
333
					'year'  => date( 'Y', strtotime( $query_args['date']['start'] ) ),
334
					'month' => date( 'm', strtotime( $query_args['date']['start'] ) ),
335
					'day'   => date( 'd', strtotime( $query_args['date']['start'] ) ),
336
				);
337
			}
338
339
			if ( ! empty( $query_args['date']['end'] ) ) {
340
				$query_args['date']['before'] = array(
341
					'year'  => date( 'Y', strtotime( $query_args['date']['end'] ) ),
342
					'month' => date( 'm', strtotime( $query_args['date']['end'] ) ),
343
					'day'   => date( 'd', strtotime( $query_args['date']['end'] ) ),
344
				);
345
			}
346
		}
347
348
		$logs = $this->log_db->get_logs( $query_args );
349
350
		if ( $logs ) {
351
			return $logs;
352
		}
353
354
		// No logs found
355
		return false;
356
	}
357
358
	/**
359
	 * Retrieve Log Count
360
	 *
361
	 * Retrieves number of log entries connected to particular object ID.
362
	 *
363
	 * @since  1.0
364
	 * @access public
365
	 *
366
	 * @param  int    $object_id  Log object ID. Default is 0.
367
	 * @param  string $type       Log type. Default is null.
368
	 * @param  array  $meta_query Log meta query. Default is null.
369
	 * @param  array  $date_query Log data query. Default is null.
370
	 *
371
	 * @return int                Log count.
372
	 */
373
	public function get_log_count( $object_id = 0, $type = null, $meta_query = null, $date_query = null ) {
374
		$log_query = array(
375
			'log_type'   => $type,
376
			'meta_query' => $meta_query,
377
			'date_query' => $date_query,
378
		);
379
380
		if ( $object_id ) {
381
			$log_query['meta_query'] = array(
382
				array(
383
					'key'   => '_give_log_form_id',
384
					'value' => $object_id,
385
				),
386
			);
387
		}
388
389
		return $this->log_db->count( $log_query );
390
	}
391
392
	/**
393
	 * Delete Logs
394
	 *
395
	 * Remove log entries connected to particular object ID.
396
	 *
397
	 * @since  1.0
398
	 * @access public
399
	 *
400
	 * @param  int    $object_id  Log object ID. Default is 0.
401
	 * @param  string $type       Log type. Default is null.
402
	 * @param  array  $meta_query Log meta query. Default is null.
403
	 *
404
	 * @return void
405
	 */
406
	public function delete_logs( $object_id = 0, $type = null, $meta_query = null ) {
407
		$query_args = array(
408
			'post_parent'    => $object_id,
409
			'post_type'      => 'give_log',
410
			'posts_per_page' => - 1,
411
			'post_status'    => 'publish',
412
			'fields'         => 'ids',
413
		);
414
415
		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
416
			$query_args['tax_query'] = array(
417
				array(
418
					'taxonomy' => 'give_log_type',
419
					'field'    => 'slug',
420
					'terms'    => $type,
421
				),
422
			);
423
		}
424
425
		if ( ! empty( $meta_query ) ) {
426
			$query_args['meta_query'] = $meta_query;
427
		}
428
429
		$logs = get_posts( $query_args );
430
431
		if ( $logs ) {
432
			foreach ( $logs as $log ) {
433
				wp_delete_post( $log, true );
434
			}
435
		}
436
	}
437
438
	/**
439
	 * Setup cron to delete log cache in background.
440
	 *
441
	 * @since  1.7
442
	 * @access public
443
	 *
444
	 * @param int $post_id
445
	 */
446
	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...
447
		// Delete log cache immediately
448
		wp_schedule_single_event( time(), 5, 'give_delete_log_cache' );
449
	}
450
451
	/**
452
	 * Delete all logging cache when form, log or payment updates
453
	 *
454
	 * @since  1.7
455
	 * @access public
456
	 *
457
	 * @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...
458
	 */
459
	public function delete_cache() {
460
		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...
461
462
		// Add log related keys to delete.
463
		$cache_option_names = $wpdb->get_col(
464
			$wpdb->prepare(
465
				"SELECT *
466
 						FROM {$wpdb->options}
467
 						where option_name LIKE '%%%s%%'
468
 						OR option_name LIKE '%%%s%%'",
469
				'give_cache_get_logs',
470
				'give_cache_get_log_count'
471
			),
472
			1 // option_name
473
		);
474
475
		// Bailout.
476
		if ( empty( $cache_option_names ) ) {
477
			return false;
478
		}
479
480
		Give_Cache::delete( $cache_option_names );
481
	}
482
}
483
484
/**
485
 * Record a log entry
486
 *
487
 * A wrapper function for the Give_Logging class add() method.
488
 *
489
 * @since  1.0
490
 * @since  2.0 Use global logs object
491
 *
492
 * @param  string $title   Log title. Default is empty.
493
 * @param  string $message Log message. Default is empty.
494
 * @param  int    $parent  Parent log. Default is 0.
495
 * @param  string $type    Log type. Default is null.
496
 *
497
 * @return int             ID of the new log entry.
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer?

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...
498
 */
499
function give_record_log( $title = '', $message = '', $parent = 0, $type = null ) {
500
	return Give()->logs->add( $title, $message, $parent, $type );
501
}
502