Changeset 3115598
- Timestamp:
- 07/10/2024 12:34:06 PM (4 weeks ago)
- Location:
- wp-blame
- Files:
-
- 9 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
wp-blame/trunk/class-log-list.php
r1815341 r3115598 6 6 class WPB_Log_List extends WP_List_Table { 7 7 8 /** 9 * Initialise the logs table. 10 * 11 * @since 2.0 12 * 13 * @return void 14 */ 15 public function __construct() { 16 17 parent::__construct( 18 array( 19 'singular' => __('Log', 'wp-blame'), 20 'plural' => __('Logs', 'wp-blame'), 21 'ajax' => false 22 ) 23 ); 24 25 $this->prepare_items(); 26 27 } 28 29 /** 30 * Define the table columns. 31 * 32 * @since 2.0 33 * 34 * @return void 35 */ 36 public function get_columns() { 37 38 $columns = [ 39 'cb' => '<input type="checkbox" />', 40 'log_id' => __('Log', 'wp-blame'), 41 'item' => __('Item', 'wp-blame'), 42 'action' => __('Action', 'wp-blame'), 43 'user_id' => __('User', 'wp-blame'), 44 'notes' => __('Notes', 'wp-blame'), 45 'timestamp' => __('Date', 'wp-blame') 46 ]; 47 48 return $columns; 49 50 } 51 52 /** 53 * Set which columns are sortable. 54 * 55 * @since 2.0 56 * 57 * @return void 58 */ 59 public function get_sortable_columns() { 60 61 $sortable_columns = array( 62 'timestamp' => array('timestamp', false) 63 ); 64 65 return $sortable_columns; 66 67 } 68 69 /** 70 * Return the checkbox column. 71 * 72 * @since 2.0 73 * 74 * @param object $item Current row item. 75 * 76 * @return string 77 */ 78 public function column_cb( $item ) { 79 80 return sprintf('<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item->log_id ); 81 82 } 83 84 /** 85 * Return the log id column. 86 * 87 * @since 2.0 88 * 89 * @param object $item Current row item. 90 * 91 * @return string 92 */ 93 public function column_log_id( $item ) { 94 95 return $item->log_id; 96 97 } 98 99 /** 100 * Return the log type column. 101 * 102 * @since 2.0 103 * 104 * @param object $item Current row item. 105 * 106 * @return string 107 */ 108 public function column_item( $item ) { 109 110 if ( 'post' == $item->slug ) { 111 112 $name = ! empty( get_the_title( $item->object_id ) ) ? get_the_title( $item->object_id ) : __('Post', 'wp-blame'); 113 $link = esc_url( admin_url('post.php?post=' . $item->object_id . '&action=edit') ); 114 115 } elseif ( 'term' == $item->slug ) { 116 117 $term = get_term( $item->object_id ); 118 $name = ! empty( $term->name ) ? $term->name : __('Term', 'wp-blame'); 119 $link = esc_url( admin_url('term.php?tag_ID=' . $item->object_id) ); 120 121 } elseif ( 'media' == $item->slug ) { 122 123 $name = ! empty( get_the_title( $item->object_id ) ) ? get_the_title( $item->object_id ) : __('Media', 'wp-blame'); 124 $link = esc_url( admin_url('upload.php?item=' . $item->object_id) ); 125 126 } elseif ( 'comment' == $item->slug ) { 127 128 $name = sprintf( _x('Comment %s', 'Comment id', 'wp-blame'), $item->object_id ); 129 $link = esc_url( admin_url('comment.php?action=editcomment&c=' . $item->object_id) ); 130 131 } elseif ( 'user' == $item->slug ) { 132 133 $name = sprintf( _x('User %s', 'User id', 'wp-blame'), $item->object_id ); 134 $link = esc_url( admin_url('user-edit.php?user_id=' . $item->object_id) ); 135 136 } elseif ( 'theme' == $item->slug ) { 137 138 $name = __('Theme', 'wp-blame'); 139 $link = esc_url( admin_url('themes.php') ); 140 141 } elseif ( 'plugin' == $item->slug ) { 142 143 $name = __('Plugin', 'wp-blame'); 144 $link = esc_url( admin_url('plugins.php') ); 145 146 } elseif ( 'option' == $item->slug ) { 147 148 $name = __('Option', 'wp-blame'); 149 $link = esc_url( admin_url('options.php') ); 150 151 } else { 152 153 return '<abbr title="' . __('Item could not be found.', 'wp-blame') . '">' . __('Not Found', 'wp-blame') . '</abbr>'; 154 155 } 156 157 return '<a href="' . $link . '">' . $name . '</a>'; 158 159 } 160 161 /** 162 * Return the log action column. 163 * 164 * @since 2.0 165 * 166 * @param object $item Current row item. 167 * 168 * @return string 169 */ 170 public function column_action( $item ) { 171 172 return $item->action; 173 174 } 175 176 /** 177 * Return the user column. 178 * 179 * @since 2.0 180 * 181 * @param object $item Current row item. 182 * 183 * @return string 184 */ 185 public function column_user_id( $item ) { 186 187 $get_user_data = get_userdata( $item->user_id ); 188 189 if ( ! empty( $get_user_data ) ) { 190 191 $get_display_name = $get_user_data->display_name; 192 193 if ( ! empty( $item->host_ip ) ) { 194 195 return '<a href="' . admin_url('user-edit.php?user_id=') . $item->user_id . '" class="profile" title="' . __('IP: ', 'wp-blame') . $item->host_ip . '">' . $get_display_name . '</a>'; 196 197 } else { 198 199 return '<a href="' . admin_url('user-edit.php?user_id=') . $item->user_id . '" class="profile">' . $get_display_name . '</a>'; 200 201 } 202 203 } else { 204 205 return '<abbr title="' . __('IP: ', 'wp-blame') . $item->host_ip . '">' . __('Unknown', 'wp-blame') . '</abbr>'; 206 207 } 208 209 } 210 211 /** 212 * Return the notes column. 213 * 214 * @since 2.0 215 * 216 * @param object $item Current row item. 217 * 218 * @return string 219 */ 220 public function column_notes( $item ) { 221 222 return $item->notes; 223 224 } 225 226 /** 227 * Return the time stamp column. 228 * 229 * @since 2.0 230 * 231 * @param object $item Current row item. 232 * 233 * @return string 234 */ 235 public function column_timestamp( $item ) { 236 237 return '<abbr title="' . date( _x('F jS Y H:i:s a', 'PHP date format', 'wp-blame'), strtotime( $item->timestamp ) ) . '">' . date( 'Y/m/d', strtotime( $item->timestamp ) ) . '</abbr>'; 238 239 } 240 241 /** 242 * Return the default (unknown) column. 243 * 244 * @since 2.0 245 * 246 * @param object $item Current row item. 247 * 248 * @return string 249 */ 250 public function column_default( $item, $column_name ) { 251 252 return $item->$column_name; 253 254 } 255 256 /** 257 * Return the no logs found notice. 258 * 259 * @since 2.0 260 * 261 * @return string 262 */ 263 public function no_items() { 264 265 _e('There are no logs to show right now.', 'wp-blame'); 266 267 } 268 269 /** 270 * Define the bulk option items. 271 * 272 * @since 2.0 273 * 274 * @return array 275 */ 276 public function get_bulk_actions() { 277 278 return array( 279 'delete' => __('Delete', 'wp-blame') 280 ); 281 282 } 283 284 /** 285 * Get the total number of logs. 286 * 287 * @since 2.0 288 * 289 * @return string 290 */ 291 public function get_total_logs() { 292 293 global $wpdb; 294 295 // Query to count the log rows 296 $total_logs = $wpdb->get_var('SELECT COUNT(*) FROM ' . $wpdb->prefix . 'logs'); 297 298 return $total_logs; 299 300 } 301 302 /** 303 * Process the bulk actions. 304 * 305 * @since 2.0 306 * 307 * @return void 308 */ 309 public function process_bulk_action() { 310 311 global $wpdb; 312 313 if ( isset( $_POST['_wpnonce'] ) ) { 314 315 $nonce = sanitize_text_field( $_POST['_wpnonce'] ); 316 $action = $this->current_action(); 317 318 if ( wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) && isset( $_POST['log'] ) && 'delete' == $action ) { 319 320 foreach ( $_POST['log'] as $log ) { 321 322 $log = sanitize_text_field( $log ); 323 324 $wpdb->query( 325 $wpdb->prepare( 326 'DELETE FROM ' . $wpdb->prefix . 'logs WHERE log_id = %s LIMIT 1', 327 $log 328 ) 329 ); 330 331 } 332 333 } 334 335 } 336 337 } 338 339 /** 340 * Prepare the items for output. 341 * 342 * @since 2.0 343 * 344 * @return void 345 */ 346 public function prepare_items() { 347 348 global $wpdb; 349 350 $screen = get_current_screen(); 351 $per_page = get_user_meta( get_current_user_id(), 'wpb_logs_per_page', true ); 352 353 if ( false === $per_page || $per_page < 1 ) { 354 355 $per_page = $screen->get_option( 'wpb_logs_per_page', 20 ); 356 357 } 358 359 $columns = $this->get_columns(); 360 $hidden = array(); 361 $sortable = $this->get_sortable_columns(); 362 $this->_column_headers = array( $columns, $hidden, $sortable ); 363 $this->process_bulk_action(); 364 365 $current_page = $this->get_pagenum(); 366 $total_items = $this->get_total_logs(); 367 368 $this->set_pagination_args([ 369 'total_items' => $total_items, 370 'per_page' => $per_page, 371 'total_pages' => ceil( $total_items / $per_page ) 372 ]); 373 374 if ( ( ! empty( $_REQUEST['orderby'] ) ) && ( ! empty( $_REQUEST['order'] ) ) ) { 375 376 $query = 'SELECT * FROM ' . $wpdb->prefix . 'logs'; 377 378 $order_by = sanitize_text_field( strtoupper( $_REQUEST['orderby'] ) ); 379 $order_col = sanitize_text_field( strtoupper( $_REQUEST['order'] ) ); 380 381 $query .= ' ORDER BY ' . $order_by; 382 $query .= $order_col == 'ASC' ? ' ' . $order_col : ' ' . $order_col; 383 384 } else { 385 386 $query = 'SELECT * FROM ' . $wpdb->prefix . 'logs ORDER BY log_id DESC'; 387 388 } 389 390 if ( $current_page >= 1 ) { 391 392 $query .= ' LIMIT ' . $per_page; 393 $query .= ' OFFSET ' . ($current_page - 1) * $per_page; 394 395 } 396 397 $this->items = $wpdb->get_results($query); 398 399 } 400 8 /** 9 * Initialise the logs table. 10 * 11 * @since 2.0 12 * 13 * @return void 14 */ 15 public function __construct() { 16 parent::__construct( 17 array( 18 'singular' => __('Log', 'wp-blame'), 19 'plural' => __('Logs', 'wp-blame'), 20 'ajax' => false 21 ) 22 ); 23 24 $this->prepare_items(); 25 } 26 27 /** 28 * Define the table columns. 29 * 30 * @since 2.0 31 * 32 * @return array 33 */ 34 public function get_columns() { 35 $columns = [ 36 'cb' => '<input type="checkbox" />', 37 'log_id' => __('Log', 'wp-blame'), 38 'item' => __('Item', 'wp-blame'), 39 'action' => __('Action', 'wp-blame'), 40 'user_id' => __('User', 'wp-blame'), 41 'notes' => __('Notes', 'wp-blame'), 42 'timestamp' => __('Date', 'wp-blame') 43 ]; 44 45 return $columns; 46 } 47 48 /** 49 * Set which columns are sortable. 50 * 51 * @since 2.0 52 * 53 * @return array 54 */ 55 public function get_sortable_columns() { 56 $sortable_columns = array( 57 'timestamp' => array('timestamp', false) 58 ); 59 60 return $sortable_columns; 61 } 62 63 /** 64 * Return the checkbox column. 65 * 66 * @since 2.0 67 * 68 * @param object $item Current row item. 69 * 70 * @return string 71 */ 72 public function column_cb( $item ) { 73 return sprintf('<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $item->log_id ); 74 } 75 76 /** 77 * Return the log id column. 78 * 79 * @since 2.0 80 * 81 * @param object $item Current row item. 82 * 83 * @return string 84 */ 85 public function column_log_id( $item ) { 86 return $item->log_id; 87 } 88 89 /** 90 * Return the log type column. 91 * 92 * @since 2.0 93 * 94 * @param object $item Current row item. 95 * 96 * @return string 97 */ 98 public function column_item( $item ) { 99 if ( 'post' == $item->slug ) { 100 $name = ! empty( get_the_title( $item->object_id ) ) ? get_the_title( $item->object_id ) : __('Post', 'wp-blame'); 101 $link = esc_url( admin_url('post.php?post=' . $item->object_id . '&action=edit') ); 102 } elseif ( 'term' == $item->slug ) { 103 $term = get_term( $item->object_id ); 104 $name = ! empty( $term->name ) ? $term->name : __('Term', 'wp-blame'); 105 $link = esc_url( admin_url('term.php?tag_ID=' . $item->object_id) ); 106 } elseif ( 'media' == $item->slug ) { 107 $name = ! empty( get_the_title( $item->object_id ) ) ? get_the_title( $item->object_id ) : __('Media', 'wp-blame'); 108 $link = esc_url( admin_url('upload.php?item=' . $item->object_id) ); 109 } elseif ( 'comment' == $item->slug ) { 110 $name = sprintf( _x('Comment %s', 'Comment id', 'wp-blame'), $item->object_id ); 111 $link = esc_url( admin_url('comment.php?action=editcomment&c=' . $item->object_id) ); 112 } elseif ( 'user' == $item->slug ) { 113 $name = sprintf( _x('User %s', 'User id', 'wp-blame'), $item->object_id ); 114 $link = esc_url( admin_url('user-edit.php?user_id=' . $item->object_id) ); 115 } elseif ( 'theme' == $item->slug ) { 116 $name = __('Theme', 'wp-blame'); 117 $link = esc_url( admin_url('themes.php') ); 118 } elseif ( 'plugin' == $item->slug ) { 119 $name = __('Plugin', 'wp-blame'); 120 $link = esc_url( admin_url('plugins.php') ); 121 } elseif ( 'option' == $item->slug ) { 122 $name = __('Option', 'wp-blame'); 123 $link = esc_url( admin_url('options.php') ); 124 } else { 125 return '<abbr title="' . __('Item could not be found.', 'wp-blame') . '">' . __('Not Found', 'wp-blame') . '</abbr>'; 126 } 127 128 return '<a href="' . $link . '">' . $name . '</a>'; 129 } 130 131 /** 132 * Return the log action column. 133 * 134 * @since 2.0 135 * 136 * @param object $item Current row item. 137 * 138 * @return string 139 */ 140 public function column_action( $item ) { 141 return $item->action; 142 } 143 144 /** 145 * Return the user column. 146 * 147 * @since 2.0 148 * 149 * @param object $item Current row item. 150 * 151 * @return string 152 */ 153 public function column_user_id( $item ) { 154 $get_user_data = get_userdata( $item->user_id ); 155 156 if ( ! empty( $get_user_data ) ) { 157 $get_display_name = $get_user_data->display_name; 158 159 if ( ! empty( $item->host_ip ) ) { 160 return '<a href="' . admin_url('user-edit.php?user_id=') . $item->user_id . '" class="profile" title="' . __('IP: ', 'wp-blame') . $item->host_ip . '">' . $get_display_name . '</a>'; 161 } else { 162 return '<a href="' . admin_url('user-edit.php?user_id=') . $item->user_id . '" class="profile">' . $get_display_name . '</a>'; 163 } 164 } else { 165 return '<abbr title="' . __('IP: ', 'wp-blame') . $item->host_ip . '">' . __('Unknown', 'wp-blame') . '</abbr>'; 166 } 167 } 168 169 /** 170 * Return the notes column. 171 * 172 * @since 2.0 173 * 174 * @param object $item Current row item. 175 * 176 * @return string 177 */ 178 public function column_notes( $item ) { 179 return $item->notes; 180 } 181 182 /** 183 * Return the time stamp column. 184 * 185 * @since 2.0 186 * 187 * @param object $item Current row item. 188 * 189 * @return string 190 */ 191 public function column_timestamp( $item ) { 192 return '<abbr title="' . date( _x('F jS Y H:i:s a', 'PHP date format', 'wp-blame'), strtotime( $item->timestamp ) ) . '">' . date( 'Y/m/d', strtotime( $item->timestamp ) ) . '</abbr>'; 193 } 194 195 /** 196 * Return the default (unknown) column. 197 * 198 * @since 2.0 199 * 200 * @param object $item Current row item. 201 * @param string $column_name Column name. 202 * 203 * @return string 204 */ 205 public function column_default( $item, $column_name ) { 206 return $item->$column_name; 207 } 208 209 /** 210 * Return the no logs found notice. 211 * 212 * @since 2.0 213 * 214 * @return void 215 */ 216 public function no_items() { 217 _e('There are no logs to show right now.', 'wp-blame'); 218 } 219 220 /** 221 * Define the bulk option items. 222 * 223 * @since 2.0 224 * 225 * @return array 226 */ 227 public function get_bulk_actions() { 228 return array( 229 'delete' => __('Delete', 'wp-blame') 230 ); 231 } 232 233 /** 234 * Get the total number of logs. 235 * 236 * @since 2.0 237 * 238 * @return int 239 */ 240 public function get_total_logs() { 241 global $wpdb; 242 243 // Query to count the log rows 244 $total_logs = $wpdb->get_var('SELECT COUNT(*) FROM ' . $wpdb->prefix . 'logs'); 245 246 return intval($total_logs); 247 } 248 249 /** 250 * Process the bulk actions. 251 * 252 * @since 2.0 253 * 254 * @return void 255 */ 256 public function process_bulk_action() { 257 global $wpdb; 258 259 if ( isset( $_POST['_wpnonce'] ) ) { 260 $nonce = sanitize_text_field( $_POST['_wpnonce'] ); 261 $action = $this->current_action(); 262 263 if ( wp_verify_nonce( $nonce, 'bulk-' . $this->_args['plural'] ) && isset( $_POST['log'] ) && 'delete' == $action ) { 264 foreach ( $_POST['log'] as $log ) { 265 $log = sanitize_text_field( $log ); 266 267 $wpdb->query( 268 $wpdb->prepare( 269 'DELETE FROM ' . $wpdb->prefix . 'logs WHERE log_id = %s LIMIT 1', 270 $log 271 ) 272 ); 273 } 274 } 275 } 276 } 277 278 /** 279 * Prepare the items for output. 280 * 281 * @since 2.0 282 * 283 * @return void 284 */ 285 public function prepare_items() { 286 global $wpdb; 287 288 $screen = get_current_screen(); 289 $per_page = get_user_meta( get_current_user_id(), 'wpb_logs_per_page', true ); 290 291 if ( false === $per_page || $per_page < 1 ) { 292 $per_page = $screen->get_option( 'per_page', 'default' ) ?: 20; 293 } 294 295 // Ensure $per_page is at least 1 296 $per_page = max(1, intval($per_page)); 297 298 $columns = $this->get_columns(); 299 $hidden = array(); 300 $sortable = $this->get_sortable_columns(); 301 $this->_column_headers = array( $columns, $hidden, $sortable ); 302 $this->process_bulk_action(); 303 304 $current_page = $this->get_pagenum(); 305 $total_items = $this->get_total_logs(); 306 307 $this->set_pagination_args([ 308 'total_items' => $total_items, 309 'per_page' => $per_page, 310 'total_pages' => $total_items > 0 ? ceil( $total_items / $per_page ) : 1 311 ]); 312 313 $order_by = ! empty( $_REQUEST['orderby'] ) ? sanitize_text_field( $_REQUEST['orderby'] ) : 'log_id'; 314 $order = ! empty( $_REQUEST['order'] ) ? sanitize_text_field( $_REQUEST['order'] ) : 'DESC'; 315 316 $query = $wpdb->prepare( 317 "SELECT * FROM {$wpdb->prefix}logs ORDER BY %s %s LIMIT %d OFFSET %d", 318 $order_by, 319 $order, 320 $per_page, 321 ($current_page - 1) * $per_page 322 ); 323 324 $this->items = $wpdb->get_results($query); 325 } 401 326 } 402 -
wp-blame/trunk/readme.txt
r3060600 r3115598 4 4 Donate link: https://wpcorner.co/donate 5 5 Requires at least: 4.0 6 Tested up to: 6. 56 Tested up to: 6. 7 7 Requires PHP: 5.4 8 Stable tag: 2.1. 58 Stable tag: 2.1. 9 9 License: GNU GPL v2 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 16 16 = About = 17 17 18 WP Blame lets you keep a record of everything that has happened on your website by logging the actions of your users in a simple but useful table of data. 18 WP Blame lets you keep a record of everything that has happened on your website by logging the actions of your users in a simple but useful table of data. 19 20 This plugin is your go-to solution for maintaining a complete audit trail of all user activities on your WordPress site. Whether you're a site administrator, developer, or security professional, WP Blame provides you with the insights you need to keep your site secure and well-managed. 21 22 = Key Features = 23 24 * **Comprehensive Logging:** Track all user actions including post edits, plugin activations, theme changes, and more. 25 * **User-Friendly Interface:** View all logged activities in an easy-to-read table right in your WordPress admin area. 26 * **Detailed Information:** Each log entry includes the user, action type, affected item, and date stamp. 27 * **User-Based Log Control:** Decide which usernames of people who should not have their actions logged. 28 29 = Perfect For = 30 31 * Troubleshooting unexpected changes 32 * Monitoring user activity for security purposes 33 * Maintaining compliance with audit requirements 34 * Tracking the history of your site's development and content changes 19 35 20 36 = Developers = … … 22 38 There are currently no hooks available for this plugin as of yet, however whilst it is discouraged, you can log actions using the `WPB_Log_Hooks::save_new_log` function. 23 39 40 41 42 43 44 45 46 47 48 24 49 == Screenshots == 25 50 26 51 1. An example of the logs table. 52 27 53 28 54 == Installation == 29 55 30 1. Download, unzip and upload the package to your plugins directory.31 2. Log into the dashboard and activate within the plugins page.32 3. Review your website logs under Tools > Logs.56 1. 57 2. 58 3. 33 59 34 60 == Frequently Asked Questions == … … 46 72 You can add usernames to a whitelist of people who's actions should not be logged on the website. 47 73 74 75 76 77 48 78 == Changelog == 79 80 81 82 83 84 49 85 50 86 = 2.1.5 = … … 85 121 == Upgrade Notice == 86 122 87 = 2.1. 4=123 = 2.1. = 88 124 89 * Minor fix125 * -
wp-blame/trunk/wp-blame.php
r3060600 r3115598 8 8 * Author URI: https://wpcorner.co/author/patrick-l/ 9 9 * Text Domain: wp-blame 10 * Version: 2.1. 510 * Version: 2.1. 11 11 */ 12 12 … … 331 331 332 332 } 333
Note: See TracChangeset
for help on using the changeset viewer.