GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#175)
by Chris
04:24
created

WP_Logging::insert_log()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 35
rs 8.439
ccs 0
cts 19
cp 0
crap 42
1
<?php
2
3
/**
4
 * Class for logging events and errors
5
 *
6
 * @package     WP Logging Class
7
 * @copyright   Copyright (c) 2012, Pippin Williamson
8
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
9
*/
10
11
class WP_Logging {
12
13
14
	/**
15
	 * Class constructor.
16
	 *
17
	 * @since 1.0
18
	 *
19
	 * @access public
20
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
21
	 */
22
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
23
24
		// create the log post type
25
		add_action( 'init', array( $this, 'register_post_type' ) );
26
27
		// create types taxonomy and default types
28
		add_action( 'init', array( $this, 'register_taxonomy' ) );
29
30
		// make a cron job for this hook to start pruning
31
		add_action( 'wp_logging_prune_routine', array( $this, 'prune_logs' ) );
32
33
	}
34
35
	/**
36
	 * Allows you to tie in a cron job and prune old logs.
37
	 *
38
	 * @since 1.1
39
	 * @access public
40
	 *
41
	 * @uses $this->get_logs_to_prune()     Returns array of posts via get_posts of logs to prune
42
	 * @uses $this->prune_old_logs()        Deletes the logs that we don't want anymore
43
	 */
44
	public function prune_logs(){
45
46
		$should_we_prune = apply_filters( 'wp_logging_should_we_prune', false );
47
48
		if ( $should_we_prune === false ){
49
			return;
50
		}
51
52
		$logs_to_prune = $this->get_logs_to_prune();
53
54
		if ( isset( $logs_to_prune ) && ! empty( $logs_to_prune ) ){
55
			$this->prune_old_logs( $logs_to_prune );
56
		}
57
58
	} // prune_logs
59
60
	/**
61
	 * Deletes the old logs that we don't want
62
	 *
63
	 * @since 1.1
64
	 * @access private
65
	 *
66
	 * @param array/obj     $logs     required     The array of logs we want to prune
0 ignored issues
show
Documentation introduced by
The doc-type array/obj could not be parsed: Unknown type name "array/obj" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
67
	 *
68
	 * @uses wp_delete_post()                      Deletes the post from WordPress
69
	 *
70
	 * @filter wp_logging_force_delete_log         Allows user to override the force delete setting which bypasses the trash
71
	 */
72
	private function prune_old_logs( $logs ){
73
74
		$force = apply_filters( 'wp_logging_force_delete_log', true );
75
76
		foreach( $logs as $l ){
77
			wp_delete_post( $l->ID, $force );
78
		}
79
80
	} // prune_old_logs
81
82
	/**
83
	 * Returns an array of posts that are prune candidates.
84
	 *
85
	 * @since 1.1
86
	 * @access private
87
	 *
88
	 * @return array     $old_logs     The array of posts that were returned from get_posts
89
	 *
90
	 * @uses apply_filters()           Allows users to change given args
91
	 * @uses get_posts()               Returns an array of posts from given args
92
	 *
93
	 * @filter wp_logging_prune_when           Users can change how long ago we are looking for logs to prune
94
	 * @filter wp_logging_prune_query_args     Gives users access to change any query args for pruning
95
	 */
96
	private function get_logs_to_prune(){
97
98
		$how_old = apply_filters( 'wp_logging_prune_when', '2 weeks ago' );
99
100
		$args = array(
101
			'post_type'      => 'wp_log',
102
			'posts_per_page' => '100',
103
			'date_query'     => array(
104
				array(
105
					'column' => 'post_date_gmt',
106
					'before' => (string) $how_old,
107
				)
108
			)
109
		);
110
111
		$old_logs = get_posts( apply_filters( 'wp_logging_prune_query_args', $args ) );
112
113
		return $old_logs;
114
115
	} // get_logs_to_prune
116
117
	/**
118
	 * Log types
119
	 *
120
	 * Sets up the default log types and allows for new ones to be created
121
	 *
122
	 * @access      private
123
	 * @since       1.0
124
	 *
125
	 * @return     array
126
	*/
127
128
	private static function log_types() {
129
		$terms = array(
130
			'error', 'event'
131
		);
132
133
		return apply_filters( 'wp_log_types', $terms );
134
	}
135
136
137
	/**
138
	 * Registers the wp_log Post Type
139
	 *
140
	 * @access      public
141
	 * @since       1.0
142
	 *
143
	 * @uses 		register_post_type()
144
	 *
145
	 * @return     void
146
	*/
147
148
	public function register_post_type() {
149
150
		/* logs post type */
151
152
		$log_args = array(
153
			'labels'          => array( 'name' => __( 'Logs', 'wp-logging' ) ),
154
			'public'          => defined( 'WP_DEBUG' ) && WP_DEBUG,
155
			'query_var'       => false,
156
			'rewrite'         => false,
157
			'capability_type' => 'post',
158
			'supports'        => array( 'title', 'editor' ),
159
			'can_export'      => false
160
		);
161
		register_post_type( 'wp_log', apply_filters( 'wp_logging_post_type_args', $log_args ) );
162
163
	}
164
165
166
	/**
167
	 * Registers the Type Taxonomy
168
	 *
169
	 * The Type taxonomy is used to determine the type of log entry
170
	 *
171
	 * @access      public
172
	 * @since       1.0
173
	 *
174
	 * @uses 		register_taxonomy()
175
	 * @uses 		term_exists()
176
	 * @uses 		wp_insert_term()
177
	 *
178
	 * @return     void
179
	*/
180
181
	public function register_taxonomy() {
182
183
		register_taxonomy( 'wp_log_type', 'wp_log', array( 'public' => defined( 'WP_DEBUG' ) && WP_DEBUG ) );
184
185
		$types = self::log_types();
186
187
		foreach ( $types as $type ) {
188
			if( ! term_exists( $type, 'wp_log_type' ) ) {
189
				wp_insert_term( $type, 'wp_log_type' );
190
			}
191
		}
192
	}
193
194
195
	/**
196
	 * Check if a log type is valid
197
	 *
198
	 * Checks to see if the specified type is in the registered list of types
199
	 *
200
	 * @access      private
201
	 * @since       1.0
202
	 *
203
	 *
204
	 * @return     array
205
	*/
206
207
	private static function valid_type( $type ) {
208
		return in_array( $type, self::log_types() );
209
	}
210
211
212
	/**
213
	 * Create new log entry
214
	 *
215
	 * This is just a simple and fast way to log something. Use self::insert_log()
216
	 * if you need to store custom meta data
217
	 *
218
	 * @access      private
219
	 * @since       1.0
220
	 *
221
	 * @uses 		self::insert_log()
222
	 *
223
	 * @return      int The ID of the new log entry
224
	*/
225
226
	public static function add( $title = '', $message = '', $parent = 0, $type = null ) {
227
228
		$log_data = array(
229
			'post_title'   => $title,
230
			'post_content' => $message,
231
			'post_parent'  => $parent,
232
			'log_type'     => $type
233
		);
234
235
		return self::insert_log( $log_data );
236
237
	}
238
239
240
	/**
241
	 * Stores a log entry
242
	 *
243
	 * @access      private
244
	 * @since       1.0
245
	 *
246
	 * @uses 		wp_parse_args()
247
	 * @uses 		wp_insert_post()
248
	 * @uses 		update_post_meta()
249
	 * @uses 		wp_set_object_terms()
250
	 * @uses 		sanitize_key()
251
	 *
252
	 * @return      int The ID of the newly created log item
253
	*/
254
255
	public static function insert_log( $log_data = array(), $log_meta = array() ) {
256
257
		$defaults = array(
258
			'post_type'    => 'wp_log',
259
			'post_status'  => 'publish',
260
			'post_parent'  => 0,
261
			'post_content' => '',
262
			'log_type'     => false
263
		);
264
265
		$args = wp_parse_args( $log_data, $defaults );
266
267
		do_action( 'wp_pre_insert_log' );
268
269
		// store the log entry
270
		$log_id = wp_insert_post( $args );
271
272
		// set the log type, if any
273
		if( $log_data['log_type'] && self::valid_type( $log_data['log_type'] ) ) {
274
			wp_set_object_terms( $log_id, $log_data['log_type'], 'wp_log_type', false );
275
		}
276
277
278
		// set log meta, if any
279
		if( $log_id && ! empty( $log_meta ) ) {
280
			foreach( (array) $log_meta as $key => $meta ) {
281
				update_post_meta( $log_id, '_wp_log_' . sanitize_key( $key ), $meta );
282
			}
283
		}
284
285
		do_action( 'wp_post_insert_log', $log_id );
286
287
		return $log_id;
288
289
	}
290
291
292
	/**
293
	 * Update and existing log item
294
	 *
295
	 * @access      private
296
	 * @since       1.0
297
	 *
298
	 * @uses 		wp_parse_args()
299
	 * @uses 		wp_update_post()
300
	 * @uses 		update_post_meta()
301
	 *
302
	 * @return      bool True if successful, false otherwise
303
	*/
304
	public static function update_log( $log_data = array(), $log_meta = array() ) {
305
306
		do_action( 'wp_pre_update_log', $log_id );
0 ignored issues
show
Bug introduced by
The variable $log_id seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
307
308
		$defaults = array(
309
			'post_type'   => 'wp_log',
310
			'post_status' => 'publish',
311
			'post_parent' => 0
312
		);
313
314
		$args = wp_parse_args( $log_data, $defaults );
315
316
		// store the log entry
317
		$log_id = wp_update_post( $args );
318
319
		if( $log_id && ! empty( $log_meta ) ) {
320
			foreach( (array) $log_meta as $key => $meta ) {
321
				if( ! empty( $meta ) )
322
					update_post_meta( $log_id, '_wp_log_' . sanitize_key( $key ), $meta );
323
			}
324
		}
325
326
		do_action( 'wp_post_update_log', $log_id );
327
328
	}
329
330
331
	/**
332
	 * Easily retrieves log items for a particular object ID
333
	 *
334
	 * @access      private
335
	 * @since       1.0
336
	 *
337
	 * @uses 		self::get_connected_logs()
338
	 *
339
	 * @return      array
340
	*/
341
342
	public static function get_logs( $object_id = 0, $type = null, $paged = null ) {
343
		return self::get_connected_logs( array( 'post_parent' => $object_id, 'paged' => $paged, 'log_type' => $type ) );
344
345
	}
346
347
348
	/**
349
	 * Retrieve all connected logs
350
	 *
351
	 * Used for retrieving logs related to particular items, such as a specific purchase.
352
	 *
353
	 * @access  private
354
	 * @since 	1.0
355
	 *
356
	 * @uses 	wp_parse_args()
357
	 * @uses 	get_posts()
358
	 * @uses 	get_query_var()
359
	 * @uses 	self::valid_type()
360
	 *
361
	 * @return  array / false
362
	*/
363
364
	public static function get_connected_logs( $args = array() ) {
365
366
		$defaults = array(
367
			'post_parent'    => 0,
368
			'post_type'      => 'wp_log',
369
			'posts_per_page' => 10,
370
			'post_status'    => 'publish',
371
			'paged'          => get_query_var( 'paged' ),
372
			'log_type'       => false
373
		);
374
375
		$query_args = wp_parse_args( $args, $defaults );
376
377
		if( $query_args['log_type'] && self::valid_type( $query_args['log_type'] ) ) {
378
379
			$query_args['tax_query'] = array(
380
				array(
381
					'taxonomy' => 'wp_log_type',
382
					'field'    => 'slug',
383
					'terms'    => $query_args['log_type']
384
				)
385
			);
386
387
		}
388
389
		$logs = get_posts( $query_args );
390
391
		if( $logs )
392
			return $logs;
393
394
		// no logs found
395
		return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by WP_Logging::get_connected_logs of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
396
397
	}
398
399
400
	/**
401
	 * Retrieves number of log entries connected to particular object ID
402
	 *
403
	 * @access  private
404
	 * @since 	1.0
405
	 *
406
	 * @uses 	WP_Query()
407
	 * @uses 	self::valid_type()
408
	 *
409
	 * @return  int
410
	*/
411
412
	public static function get_log_count( $object_id = 0, $type = null, $meta_query = null ) {
413
414
		$query_args = array(
415
			'post_parent'    => $object_id,
416
			'post_type'      => 'wp_log',
417
			'posts_per_page' => -1,
418
			'post_status'    => 'publish'
419
		);
420
421
		if( ! empty( $type ) && self::valid_type( $type ) ) {
422
423
			$query_args['tax_query'] = array(
424
				array(
425
					'taxonomy' => 'wp_log_type',
426
					'field'    => 'slug',
427
					'terms'    => $type
428
				)
429
			);
430
431
		}
432
433
		if( ! empty( $meta_query ) ) {
434
			$query_args['meta_query'] = $meta_query;
435
		}
436
437
		$logs = new WP_Query( $query_args );
438
439
		return (int) $logs->post_count;
440
441
	}
442
443
}
444
$GLOBALS['wp_logs'] = new WP_Logging();
445