Completed
Push — master ( ae6a2e...798796 )
by Jonathan
28s queued 13s
created

Object_Sync_Sf_Logging   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 664
Duplicated Lines 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
eloc 246
c 5
b 1
f 0
dl 0
loc 664
rs 2.88
wmc 69

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 18 1
B posts_filter() 0 13 7
A add_prune_interval() 0 14 1
A configure_debugging() 0 15 3
B check_log_schedule() 0 25 6
B restrict_logs_by_type() 0 31 6
A set_prune_option() 0 4 1
A sortable_columns() 0 3 1
A get_schedule_frequency() 0 21 4
A set_log_visibility() 0 22 1
A type_column() 0 3 1
A type_column_content() 0 14 3
A set_prune_age() 0 6 2
A init() 0 31 3
A set_log_slug() 0 5 2
A save_log_schedule() 0 11 5
A set_log_types() 0 3 1
A set_prune_args() 0 7 2
A add() 0 10 1
A get_connected_logs() 0 33 4
A get_log_count() 0 28 4
B setup() 0 21 9
A get_logs() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like Object_Sync_Sf_Logging often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Object_Sync_Sf_Logging, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Log events based on plugin settings. Extend the WP_Logging class for the purposes of Object Sync for Salesforce.
4
 *
5
 * @class   Object_Sync_Sf_Logging
6
 * @package Object_Sync_Salesforce
7
 */
8
9
defined( 'ABSPATH' ) || exit;
10
11
/**
12
 * Object_Sync_Sf_Logging class.
13
 */
14
class Object_Sync_Sf_Logging extends WP_Logging {
15
16
	/**
17
	 * Current version of the plugin
18
	 *
19
	 * @var string
20
	 */
21
	public $version;
22
23
	/**
24
	 * The main plugin file
25
	 *
26
	 * @var string
27
	 */
28
	public $file;
29
30
	/**
31
	 * Global object of `$wpdb`, the WordPress database
32
	 *
33
	 * @var object
34
	 */
35
	public $wpdb;
36
37
	/**
38
	 * The plugin's slug so we can include it when necessary
39
	 *
40
	 * @var string
41
	 */
42
	public $slug;
43
44
	/**
45
	 * The plugin's prefix when saving options to the database
46
	 *
47
	 * @var string
48
	 */
49
	public $option_prefix;
50
51
	/**
52
	 * The setting value for whether logging is enabled
53
	 *
54
	 * @var bool
55
	 */
56
	public $enabled;
57
58
	/**
59
	 * Which statuses to log, from the settings value
60
	 *
61
	 * @var array
62
	 */
63
	public $statuses_to_log;
64
65
	/**
66
	 * The name of the schedule to prune logs
67
	 *
68
	 * @var string
69
	 */
70
	public $schedule_name;
71
72
	/**
73
	 * Whether the plugin is in debug mode
74
	 *
75
	 * @var bool
76
	 */
77
	public $debug;
78
79
	/**
80
	 * Constructor for logging class
81
	 */
82
	public function __construct() {
83
		$this->version       = object_sync_for_salesforce()->version;
84
		$this->file          = object_sync_for_salesforce()->file;
85
		$this->wpdb          = object_sync_for_salesforce()->wpdb;
86
		$this->slug          = object_sync_for_salesforce()->slug;
87
		$this->option_prefix = object_sync_for_salesforce()->option_prefix;
88
89
		$this->enabled         = filter_var( get_option( $this->option_prefix . 'enable_logging', false ), FILTER_VALIDATE_BOOLEAN );
90
		$this->statuses_to_log = maybe_unserialize( get_option( $this->option_prefix . 'statuses_to_log', array() ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like maybe_unserialize(get_op...uses_to_log', array())) can also be of type false. However, the property $statuses_to_log is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
91
92
		$this->schedule_name = 'wp_logging_prune_routine';
93
94
		$this->capability = 'configure_salesforce';
0 ignored issues
show
Bug Best Practice introduced by
The property capability does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
95
96
		// use the option value for whether we're in debug mode.
97
		$this->debug = filter_var( get_option( $this->option_prefix . 'debug_mode', false ), FILTER_VALIDATE_BOOLEAN );
98
99
		add_action( 'plugins_loaded', array( $this, 'init' ) );
100
101
	}
102
103
	/**
104
	 * Initialize. This creates a schedule for pruning logs, and also the custom content type
105
	 */
106
	public function init() {
107
		$this->configure_debugging();
108
		if ( true === $this->enabled ) {
109
			add_filter( 'cron_schedules', array( $this, 'add_prune_interval' ) );
110
			add_filter( 'wp_log_types', array( $this, 'set_log_types' ), 10, 1 );
111
			add_filter( 'wp_logging_should_we_prune', array( $this, 'set_prune_option' ), 10, 1 );
112
			add_filter( 'wp_logging_prune_when', array( $this, 'set_prune_age' ), 10, 1 );
113
			add_filter( 'wp_logging_prune_query_args', array( $this, 'set_prune_args' ), 10, 1 );
114
			add_filter( 'wp_logging_post_type_args', array( $this, 'set_log_visibility' ), 10, 1 );
115
			add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_log_slug' ), 10, 5 );
116
117
			// add a filter to check for other plugins that might be filtering the log screen.
118
			$are_logs_filtered = apply_filters( 'wp_logging_manage_logs_filtered', false );
0 ignored issues
show
Unused Code introduced by
The call to __return_true() has too many arguments starting with false. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
			$are_logs_filtered = /** @scrutinizer ignore-call */ apply_filters( 'wp_logging_manage_logs_filtered', false );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
119
			add_filter( 'wp_logging_manage_logs_filtered', '__return_true' );
120
121
			if ( false === $are_logs_filtered ) {
0 ignored issues
show
introduced by
The condition false === $are_logs_filtered is always false.
Loading history...
122
				// add a sortable Type column to the posts admin.
123
				add_filter( 'manage_edit-wp_log_columns', array( $this, 'type_column' ), 10, 1 );
124
				add_filter( 'manage_edit-wp_log_sortable_columns', array( $this, 'sortable_columns' ), 10, 1 );
125
				add_action( 'manage_wp_log_posts_custom_column', array( $this, 'type_column_content' ), 10, 2 );
126
127
				// filter the log posts admin by log type.
128
				add_filter( 'parse_query', array( $this, 'posts_filter' ), 10, 1 );
129
				add_action( 'restrict_manage_posts', array( $this, 'restrict_logs_by_type' ), 10, 1 );
130
			}
131
132
			// when the schedule might change.
133
			add_action( 'update_option_' . $this->option_prefix . 'logs_how_often_unit', array( $this, 'check_log_schedule' ), 10, 3 );
134
			add_action( 'update_option_' . $this->option_prefix . 'logs_how_often_number', array( $this, 'check_log_schedule' ), 10, 3 );
135
136
			$this->save_log_schedule();
137
		}
138
	}
139
140
	/**
141
	 * Configure log settings based on debug status.
142
	 */
143
	private function configure_debugging() {
144
		// set debug log status based on the plugin's debug mode setting.
145
		if ( true === $this->debug ) {
146
			$this->statuses_to_log[] = 'debug';
147
			$this->enabled           = true;
148
		} else {
149
			if ( in_array( 'debug', $this->statuses_to_log, true ) ) {
150
				$delete_value          = 'debug';
151
				$this->statuses_to_log = array_filter(
152
					$this->statuses_to_log,
153
					function( $e ) use ( $delete_value ) {
154
						return ( $e !== $delete_value );
155
					}
156
				);
157
				update_option( $this->option_prefix . 'statuses_to_log', $this->statuses_to_log );
158
			}
159
		}
160
	}
161
162
	/**
163
	 * Set visibility for the post type
164
	 *
165
	 * @param array $log_args The post arguments.
166
	 * @return array $log_args
167
	 */
168
	public function set_log_visibility( $log_args ) {
169
		// set public to true overrides the WP_DEBUG setting that is the default on the class
170
		// capabilities makes it so (currently) only admin users can see the log posts in their admin view
171
		// note: a public value of true is required to show Logs as a nav menu item on the admin.
172
		// however, if we don't set exclude_from_search to true and publicly_queryable to false, logs *can* appear in search results.
173
		$log_args['public']              = true;
174
		$log_args['publicly_queryable']  = false;
175
		$log_args['exclude_from_search'] = true;
176
		$log_args['capabilities']        = array(
177
			'edit_post'          => $this->capability,
178
			'read_post'          => $this->capability,
179
			'delete_post'        => $this->capability,
180
			'edit_posts'         => $this->capability,
181
			'edit_others_posts'  => $this->capability,
182
			'delete_posts'       => $this->capability,
183
			'publish_posts'      => $this->capability,
184
			'read_private_posts' => $this->capability,
185
		);
186
187
		$log_args = apply_filters( $this->option_prefix . 'logging_post_type_args', $log_args );
188
189
		return $log_args;
190
	}
191
192
	/**
193
	 * Create a (probably unique) post name for logs in a more performant manner than wp_unique_post_slug().
194
	 *
195
	 * @param string $override_slug Short-circuit return value.
196
	 * @param string $slug The desired slug (post_name).
197
	 * @param int    $post_ID The post ID.
198
	 * @param string $post_status The post status.
199
	 * @param string $post_type The post type.
200
	 * @return string
201
	 */
202
	public function set_log_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) {
203
		if ( 'wp_log' === $post_type ) {
204
			$override_slug = uniqid( $post_type . '-', true ) . '-' . wp_generate_password( 32, false );
205
		}
206
		return $override_slug;
207
	}
208
209
	/**
210
	 * Add a Type column to the posts admin for this post type
211
	 *
212
	 * @param array $columns the columns for the post list table.
213
	 * @return array $columns
214
	 */
215
	public function type_column( $columns ) {
216
		$columns['type'] = __( 'Type', 'object-sync-for-salesforce' );
217
		return $columns;
218
	}
219
220
	/**
221
	 * Make the Type column in the posts admin for this post type sortable
222
	 *
223
	 * @param array $columns the sortable columns for the post list table.
224
	 * @return array $columns
225
	 */
226
	public function sortable_columns( $columns ) {
227
		$columns['type'] = 'type';
228
		return $columns;
229
	}
230
231
	/**
232
	 * Add the content for the Type column in the posts admin for this post type
233
	 *
234
	 * @param string $column_name the value for the type column on the list table.
235
	 * @param int    $post_id the ID of the currently listed post in the table.
236
	 */
237
	public function type_column_content( $column_name, $post_id ) {
238
		if ( 'type' !== $column_name ) {
239
			return;
240
		}
241
		// get wp_log_type.
242
		$terms = wp_get_post_terms(
243
			$post_id,
244
			'wp_log_type',
245
			array(
246
				'fields' => 'names',
247
			)
248
		);
249
		if ( is_array( $terms ) ) {
250
			echo esc_attr( $terms[0] );
251
		}
252
	}
253
254
	/**
255
	 * Filter log posts by the taxonomy from the dropdown when a value is present
256
	 *
257
	 * @param object $query the current WP query for the list table.
258
	 */
259
	public function posts_filter( $query ) {
260
		global $pagenow;
261
		$type     = 'wp_log';
262
		$taxonomy = 'wp_log_type';
263
		if ( is_admin() && 'edit.php' === $pagenow ) {
264
			if ( isset( $_GET['post_type'] ) && esc_attr( $_GET['post_type'] ) === $type ) {
265
				if ( isset( $_GET[ $taxonomy ] ) && '' !== $_GET[ $taxonomy ] ) {
266
					$query->post_type = $type;
267
					$query->tax_query = array(
268
						array(
269
							'taxonomy' => $taxonomy,
270
							'field'    => 'slug',
271
							'terms'    => esc_attr( $_GET[ $taxonomy ] ),
272
						),
273
					);
274
				}
275
			}
276
		}
277
	}
278
279
	/**
280
	 * Add a filter form for the log admin so we can filter by wp_log_type taxonomy values
281
	 *
282
	 * @param string $post_type what type of log we want to show.
283
	 */
284
	public function restrict_logs_by_type( $post_type ) {
285
		$type     = 'wp_log';
286
		$taxonomy = 'wp_log_type';
287
		// only add filter to post type you want.
288
		if ( 'wp_log' === $post_type ) {
289
			// get wp_log_type.
290
			$terms = get_terms(
291
				array(
292
					'taxonomy'   => $taxonomy,
293
					'hide_empty' => true,
294
				)
295
			);
296
			if ( is_wp_error( $terms ) || empty( $terms ) ) {
297
				// no terms, or the taxonomy doesn't exist, skip.
298
				return;
299
			}
300
			?>
301
			<select name="wp_log_type">
302
				<option value=""><?php esc_html_e( 'All log types ', 'object-sync-for-salesforce' ); ?></option>
303
				<?php
304
				$current_log_type = isset( $_GET[ $taxonomy ] ) ? esc_attr( $_GET[ $taxonomy ] ) : '';
305
				foreach ( $terms as $key => $term ) {
306
					printf(
307
						'<option value="%s"%s>%s</option>',
308
						esc_attr( $term->slug ),
309
						selected( $term->slug, $current_log_type, false ),
310
						esc_html( $term->name )
311
					);
312
				}
313
				?>
314
			</select>
315
			<?php
316
		}
317
	}
318
319
	/**
320
	 * When the cron settings change, clear the relevant schedule
321
	 *
322
	 * @param string $old_value Previous option value.
323
	 * @param string $new_value New option value.
324
	 * @param string $option Name of option.
325
	 */
326
	public function check_log_schedule( $old_value, $new_value, $option ) {
327
		$clear_schedule  = false;
328
		$schedule_unit   = get_option( $this->option_prefix . 'logs_how_often_unit', '' );
329
		$schedule_number = get_option( $this->option_prefix . 'logs_how_often_number', '' );
330
		if ( $this->option_prefix . 'logs_how_often_unit' === $option ) {
331
			$old_frequency = $this->get_schedule_frequency( $old_value, $schedule_number );
0 ignored issues
show
Bug introduced by
It seems like $schedule_number can also be of type false; however, parameter $number of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

331
			$old_frequency = $this->get_schedule_frequency( $old_value, /** @scrutinizer ignore-type */ $schedule_number );
Loading history...
332
			$new_frequency = $this->get_schedule_frequency( $new_value, $schedule_number );
333
			$old_key       = $old_frequency['key'];
334
			$new_key       = $new_frequency['key'];
335
			if ( $old_key !== $new_key ) {
336
				$clear_schedule = true;
337
			}
338
		}
339
		if ( $this->option_prefix . 'logs_how_often_number' === $option ) {
340
			$old_frequency = $this->get_schedule_frequency( $schedule_unit, $old_value );
0 ignored issues
show
Bug introduced by
It seems like $schedule_unit can also be of type false; however, parameter $unit of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

340
			$old_frequency = $this->get_schedule_frequency( /** @scrutinizer ignore-type */ $schedule_unit, $old_value );
Loading history...
341
			$new_frequency = $this->get_schedule_frequency( $schedule_unit, $new_value );
342
			$old_key       = $old_frequency['key'];
343
			$new_key       = $new_frequency['key'];
344
			if ( $old_key !== $new_key ) {
345
				$clear_schedule = true;
346
			}
347
		}
348
		if ( true === $clear_schedule ) {
349
			wp_clear_scheduled_hook( $this->schedule_name );
350
			$this->save_log_schedule();
351
		}
352
	}
353
354
	/**
355
	 * Save a cron schedule
356
	 */
357
	public function save_log_schedule() {
358
		global $pagenow;
359
		if ( ( 'options.php' !== $pagenow ) && ( ! isset( $_GET['page'] ) || $this->slug . '-admin' !== $_GET['page'] ) ) {
360
			return;
361
		}
362
		$schedule_unit   = get_option( $this->option_prefix . 'logs_how_often_unit', '' );
363
		$schedule_number = get_option( $this->option_prefix . 'logs_how_often_number', '' );
364
		$frequency       = $this->get_schedule_frequency( $schedule_unit, $schedule_number );
0 ignored issues
show
Bug introduced by
It seems like $schedule_number can also be of type false; however, parameter $number of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

364
		$frequency       = $this->get_schedule_frequency( $schedule_unit, /** @scrutinizer ignore-type */ $schedule_number );
Loading history...
Bug introduced by
It seems like $schedule_unit can also be of type false; however, parameter $unit of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

364
		$frequency       = $this->get_schedule_frequency( /** @scrutinizer ignore-type */ $schedule_unit, $schedule_number );
Loading history...
365
		$key             = $frequency['key'];
366
		if ( ! wp_next_scheduled( $this->schedule_name ) ) {
367
			wp_schedule_event( time(), $key, $this->schedule_name );
368
		}
369
	}
370
371
	/**
372
	 * Add interval to wp schedules based on admin settings
373
	 *
374
	 * @param array $schedules An array of scheduled cron items.
375
	 * @return array $frequency
376
	 */
377
	public function add_prune_interval( $schedules ) {
378
379
		$schedule_unit   = get_option( $this->option_prefix . 'logs_how_often_unit', '' );
380
		$schedule_number = get_option( $this->option_prefix . 'logs_how_often_number', '' );
381
		$frequency       = $this->get_schedule_frequency( $schedule_unit, $schedule_number );
0 ignored issues
show
Bug introduced by
It seems like $schedule_unit can also be of type false; however, parameter $unit of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

381
		$frequency       = $this->get_schedule_frequency( /** @scrutinizer ignore-type */ $schedule_unit, $schedule_number );
Loading history...
Bug introduced by
It seems like $schedule_number can also be of type false; however, parameter $number of Object_Sync_Sf_Logging::get_schedule_frequency() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

381
		$frequency       = $this->get_schedule_frequency( $schedule_unit, /** @scrutinizer ignore-type */ $schedule_number );
Loading history...
382
		$key             = $frequency['key'];
383
		$seconds         = $frequency['seconds'];
384
385
		$schedules[ $key ] = array(
386
			'interval' => $seconds * $schedule_number,
387
			'display'  => 'Every ' . $schedule_number . ' ' . $schedule_unit,
0 ignored issues
show
Bug introduced by
Are you sure $schedule_unit of type false|mixed|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

387
			'display'  => 'Every ' . $schedule_number . ' ' . /** @scrutinizer ignore-type */ $schedule_unit,
Loading history...
Bug introduced by
Are you sure $schedule_number of type false|mixed|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

387
			'display'  => 'Every ' . /** @scrutinizer ignore-type */ $schedule_number . ' ' . $schedule_unit,
Loading history...
388
		);
389
390
		return $schedules;
391
392
	}
393
394
	/**
395
	 * Convert the schedule frequency from the admin settings into an array
396
	 * interval must be in seconds for the class to use it
397
	 *
398
	 * @param string $unit A unit of time.
399
	 * @param string $number The number of those units.
400
	 * @return array
401
	 */
402
	public function get_schedule_frequency( $unit, $number ) {
403
404
		switch ( $unit ) {
405
			case 'minutes':
406
				$seconds = 60;
407
				break;
408
			case 'hours':
409
				$seconds = 3600;
410
				break;
411
			case 'days':
412
				$seconds = 86400;
413
				break;
414
			default:
415
				$seconds = 0;
416
		}
417
418
		$key = $unit . '_' . $number;
419
420
		return array(
421
			'key'     => $key,
422
			'seconds' => $seconds,
423
		);
424
425
	}
426
427
	/**
428
	 * Set terms for Salesforce logs
429
	 *
430
	 * @param array $terms An array of string log types in the WP_Logging class.
431
	 * @return array $terms
432
	 */
433
	public function set_log_types( $terms ) {
434
		$terms[] = 'salesforce';
435
		return $terms;
436
	}
437
438
	/**
439
	 * Should logs be pruned at all?
440
	 *
441
	 * @param string $should_we_prune Whether to prune old log items.
442
	 * @return string $should_we_prune Whether to prune old log items.
443
	 */
444
	public function set_prune_option( $should_we_prune ) {
445
		$should_we_prune = get_option( $this->option_prefix . 'prune_logs', $should_we_prune );
446
		$should_we_prune = filter_var( $should_we_prune, FILTER_VALIDATE_BOOLEAN );
447
		return $should_we_prune;
448
	}
449
450
	/**
451
	 * Set how often to prune the Salesforce logs
452
	 *
453
	 * @param string $how_old How old the oldest non-pruned log items should be allowed to be.
454
	 * @return string $how_old
455
	 */
456
	public function set_prune_age( $how_old ) {
457
		$value = get_option( $this->option_prefix . 'logs_how_old', '' ) . ' ago';
0 ignored issues
show
Bug introduced by
Are you sure get_option($this->option...x . 'logs_how_old', '') of type false|mixed|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

457
		$value = /** @scrutinizer ignore-type */ get_option( $this->option_prefix . 'logs_how_old', '' ) . ' ago';
Loading history...
458
		if ( '' !== $value ) {
459
			return $value;
460
		} else {
461
			return $how_old;
462
		}
463
	}
464
465
	/**
466
	 * Set arguments for only getting the Salesforce logs
467
	 *
468
	 * @param array $args Argument array for get_posts determining what posts are eligible for pruning.
469
	 * @return array $args
470
	 */
471
	public function set_prune_args( $args ) {
472
		$args['wp_log_type'] = 'salesforce';
473
		$number_to_prune     = get_option( $this->option_prefix . 'logs_how_many_number', '' );
474
		if ( '' !== $number_to_prune ) {
475
			$args['posts_per_page'] = filter_var( $number_to_prune, FILTER_SANITIZE_NUMBER_INT );
476
		}
477
		return $args;
478
	}
479
480
	/**
481
	 * Setup new log entry
482
	 *
483
	 * Check and see if we should log anything, and if so, send it to add()
484
	 *
485
	 * @access      public
486
	 * @since       1.0
487
	 *
488
	 * @param       string|array $title_or_params A log post title, or the full array of parameters.
489
	 * @param       string       $message The log message.
490
	 * @param       string|0     $trigger The type of log triggered. Usually one of: debug, notice, warning, error.
0 ignored issues
show
Documentation Bug introduced by
The doc comment string|0 at position 2 could not be parsed: Unknown type name '0' at position 2 in string|0.
Loading history...
491
	 * @param       int          $parent The parent WordPress object.
492
	 * @param       string       $status The log status.
493
	 *
494
	 * @uses        self::add()
495
	 * @see         Object_Sync_Sf_Mapping::__construct()    the location of the parameters that define the logging triggers.
496
	 *
497
	 * @return      void
498
	 */
499
	public function setup( $title_or_params, $message = '', $trigger = 0, $parent = 0, $status = '' ) {
500
501
		if ( is_array( $title_or_params ) ) {
502
			$title   = $title_or_params['title'];
503
			$message = $title_or_params['message'];
504
			$trigger = $title_or_params['trigger'];
505
			$parent  = $title_or_params['parent'];
506
			$status  = $title_or_params['status'];
507
		} else {
508
			$title = $title_or_params;
509
		}
510
511
		if ( true === $this->enabled && in_array( $status, $this->statuses_to_log, true ) ) {
512
			$triggers_to_log = maybe_unserialize( get_option( $this->option_prefix . 'triggers_to_log', array() ) );
513
			if ( in_array( $trigger, $triggers_to_log, true ) || 0 === $trigger ) {
0 ignored issues
show
Bug introduced by
It seems like $triggers_to_log can also be of type false; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

513
			if ( in_array( $trigger, /** @scrutinizer ignore-type */ $triggers_to_log, true ) || 0 === $trigger ) {
Loading history...
514
				$this->add( $title, $message, $parent );
515
			} elseif ( is_array( $trigger ) && array_intersect( $trigger, $triggers_to_log ) ) {
0 ignored issues
show
Bug introduced by
It seems like $triggers_to_log can also be of type false; however, parameter $arrays of array_intersect() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

515
			} elseif ( is_array( $trigger ) && array_intersect( $trigger, /** @scrutinizer ignore-type */ $triggers_to_log ) ) {
Loading history...
516
				$this->add( $title, $message, $parent );
517
			} elseif ( true === $this->debug ) {
518
				// if the plugin is in debug mode, treat all triggers as triggers to log.
519
				$this->add( $title, $message, $parent );
520
			}
521
		}
522
	}
523
524
	/**
525
	 * Create new log entry
526
	 *
527
	 * This is just a simple and fast way to log something. Use self::insert_log()
528
	 * if you need to store custom meta data
529
	 *
530
	 * @access      public
531
	 * @since       1.0
532
	 *
533
	 * @param       string $title A log post title.
534
	 *
535
	 * @uses        self::insert_log()
536
	 * @param       string $message The log message.
537
	 * @param       int    $parent The parent WordPress object.
538
	 * @param       string $type The type of log message; defaults to 'salesforce'.
539
	 *
540
	 * @return      int The ID of the new log entry
541
	 */
542
	public static function add( $title = '', $message = '', $parent = 0, $type = 'salesforce' ) {
543
544
		$log_data = array(
545
			'post_title'   => esc_html( $title ),
546
			'post_content' => wp_kses_post( $message ),
547
			'post_parent'  => absint( $parent ),
548
			'log_type'     => esc_attr( $type ),
549
		);
550
551
		return self::insert_log( $log_data );
552
553
	}
554
555
556
	/**
557
	 * Easily retrieves log items for a particular object ID
558
	 *
559
	 * @access      private
560
	 * @since       1.0
561
	 *
562
	 * @param       int    $object_id A WordPress object ID.
563
	 * @param       string $type The type of log item; defaults to 'salesforce' because that's the type of logs we create.
564
	 * @param       int    $paged show which page of results we want.
565
	 *
566
	 * @uses        self::get_connected_logs()
567
	 *
568
	 * @return      array
569
	 */
570
	public static function get_logs( $object_id = 0, $type = 'salesforce', $paged = null ) {
571
		return self::get_connected_logs(
572
			array(
573
				'post_parent' => (int) $object_id,
574
				'paged'       => (int) $paged,
575
				'log_type'    => (string) $type,
576
			)
577
		);
578
	}
579
580
581
	/**
582
	 * Retrieve all connected logs
583
	 *
584
	 * Used for retrieving logs related to particular items, such as a specific purchase.
585
	 *
586
	 * @access  private
587
	 * @since   1.0
588
	 *
589
	 * @param   Array $args An array of arguments for get_posts().
590
	 *
591
	 * @uses    wp_parse_args()
592
	 * @uses    get_posts()
593
	 * @uses    get_query_var()
594
	 * @uses    self::valid_type()
595
	 *
596
	 * @return  array / false
597
	 */
598
	public static function get_connected_logs( $args = array() ) {
599
600
		$defaults = array(
601
			'post_parent'    => 0,
602
			'post_type'      => 'wp_log',
603
			'posts_per_page' => 10,
604
			'post_status'    => 'publish',
605
			'paged'          => get_query_var( 'paged' ),
606
			'log_type'       => 'salesforce',
607
		);
608
609
		$query_args = wp_parse_args( $args, $defaults );
610
611
		if ( $query_args['log_type'] && self::valid_type( $query_args['log_type'] ) ) {
612
613
			$query_args['tax_query'] = array(
614
				array(
615
					'taxonomy' => 'wp_log_type',
616
					'field'    => 'slug',
617
					'terms'    => $query_args['log_type'],
618
				),
619
			);
620
621
		}
622
623
		$logs = get_posts( $query_args );
624
625
		if ( $logs ) {
626
			return $logs;
627
		}
628
629
		// no logs found.
630
		return false;
631
632
	}
633
634
635
	/**
636
	 * Retrieves number of log entries connected to particular object ID
637
	 *
638
	 * @access  private
639
	 * @since   1.0
640
	 *
641
	 * @param       int    $object_id A WordPress object ID.
642
	 * @param       string $type The type of log item; defaults to 'salesforce' because that's the type of logs we create.
643
	 * @param       array  $meta_query A WordPress meta query, parseable by WP_Meta_Query.
644
	 *
645
	 * @uses    WP_Query()
646
	 * @uses    self::valid_type()
647
	 *
648
	 * @return  int
649
	 */
650
	public static function get_log_count( $object_id = 0, $type = 'salesforce', $meta_query = null ) {
651
652
		$query_args = array(
653
			'post_parent'    => (int) $object_id,
654
			'post_type'      => 'wp_log',
655
			'posts_per_page' => 100,
656
			'post_status'    => 'publish',
657
		);
658
659
		if ( ! empty( $type ) && self::valid_type( $type ) ) {
660
661
			$query_args['tax_query'] = array(
662
				array(
663
					'taxonomy' => 'wp_log_type',
664
					'field'    => 'slug',
665
					'terms'    => sanitize_key( $type ),
666
				),
667
			);
668
669
		}
670
671
		if ( ! empty( $meta_query ) ) {
672
			$query_args['meta_query'] = $meta_query;
673
		}
674
675
		$logs = new WP_Query( $query_args );
676
677
		return (int) $logs->post_count;
678
679
	}
680
681
}
682