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() ) ); |
|
|
|
|
91
|
|
|
|
92
|
|
|
$this->schedule_name = 'wp_logging_prune_routine'; |
93
|
|
|
|
94
|
|
|
$this->capability = 'configure_salesforce'; |
|
|
|
|
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 ); |
|
|
|
|
119
|
|
|
add_filter( 'wp_logging_manage_logs_filtered', '__return_true' ); |
120
|
|
|
|
121
|
|
|
if ( false === $are_logs_filtered ) { |
|
|
|
|
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 ); |
|
|
|
|
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 ); |
|
|
|
|
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 ); |
|
|
|
|
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 ); |
|
|
|
|
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, |
|
|
|
|
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'; |
|
|
|
|
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. |
|
|
|
|
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 ) { |
|
|
|
|
514
|
|
|
$this->add( $title, $message, $parent ); |
515
|
|
|
} elseif ( is_array( $trigger ) && array_intersect( $trigger, $triggers_to_log ) ) { |
|
|
|
|
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
|
|
|
|
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 theid
property of an instance of theAccount
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.