diff --git a/admin/class-wp-rest-api-log-admin-list-table.php b/admin/class-wp-rest-api-log-admin-list-table.php index c52261e..bb7dc69 100644 --- a/admin/class-wp-rest-api-log-admin-list-table.php +++ b/admin/class-wp-rest-api-log-admin-list-table.php @@ -60,6 +60,7 @@ public function custom_columns( $columns ) { 'elapsed' => __( 'Elapsed Time', 'wp-rest-api-log' ), 'length' => __( 'Response Length', 'wp-rest-api-log' ), 'ip-address' => __( 'IP Address', 'wp-rest-api-log' ), + 'user' => __( 'User', 'wp-rest-api-log' ), ); @@ -89,6 +90,10 @@ public function custom_column( $column, $post_id ) { echo esc_html( number_format( strlen( $entry->response->body ) ) ); break; + case 'user': + echo esc_html( $entry->user ); + break; + case 'ip-address': $ip_address_display = apply_filters( WP_REST_API_Log_Common::PLUGIN_NAME . '-setting-get', 'general', diff --git a/admin/class-wp-rest-api-log-admin.php b/admin/class-wp-rest-api-log-admin.php index afd5279..31a96da 100644 --- a/admin/class-wp-rest-api-log-admin.php +++ b/admin/class-wp-rest-api-log-admin.php @@ -7,24 +7,19 @@ class WP_REST_API_Log_Admin { - public function plugins_loaded() { - add_filter( 'post_type_link', array( $this, 'entry_permalink' ), 10, 2 ); - add_filter( 'get_edit_post_link', array( $this, 'entry_permalink' ), 10, 2 ); - - add_action( 'admin_init', array( $this, 'register_scripts' ) ); - - add_action( 'admin_menu', array( $this, 'admin_menu' ) ); - - add_filter( 'wp_link_query_args', array( $this, 'wp_link_query_args' ) ); - - add_filter( 'admin_title', 'WP_REST_API_Log_Admin::admin_title', 10, 2 ); - - add_filter( 'user_has_cap', 'WP_REST_API_Log_Admin::add_admin_caps', 10, 3 ); - + static public function plugins_loaded() { + add_filter( 'post_type_link', array( __CLASS__, 'entry_permalink' ), 10, 2 ); + add_filter( 'get_edit_post_link', array( __CLASS__, 'entry_permalink' ), 10, 2 ); + add_action( 'admin_init', array( __CLASS__, 'register_scripts' ) ); + add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) ); + add_filter( 'wp_link_query_args', array( __CLASS__, 'wp_link_query_args' ) ); + add_filter( 'admin_title', array( __CLASS__, 'admin_title' ), 10, 2 ); + add_filter( 'user_has_cap', array( __CLASS__, 'add_admin_caps' ), 10, 3 ); + add_filter( 'plugin_action_links_' . WP_REST_API_LOG_BASENAME, array( __CLASS__, 'plugin_action_links' ), 10, 4 ); } - public function admin_menu() { + static public function admin_menu() { add_submenu_page( null, @@ -32,7 +27,7 @@ public function admin_menu() { '', 'read_' . WP_REST_API_Log_DB::POST_TYPE, WP_REST_API_Log_Common::PLUGIN_NAME . '-view-entry', - array( $this, 'display_log_entry') + array( __CLASS__, 'display_log_entry') ); global $submenu; @@ -50,19 +45,19 @@ public function admin_menu() { } - public function register_scripts() { + static public function register_scripts() { $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '.min' : ''; // https://highlightjs.org/ - $highlight_version = apply_filters( 'wp-rest-api-log-admin-highlight-js-version', '9.7.0' ); + $highlight_version = apply_filters( 'wp-rest-api-log-admin-highlight-js-version', '9.9.0' ); $highlight_style = apply_filters( 'wp-rest-api-log-admin-highlight-js-version', 'github' ); wp_register_script( 'wp-rest-api-log-admin-highlight-js', '//cdnjs.cloudflare.com/ajax/libs/highlight.js/' . $highlight_version . '/highlight.min.js' ); wp_register_style( 'wp-rest-api-log-admin-highlight-js', '//cdnjs.cloudflare.com/ajax/libs/highlight.js/' . $highlight_version . '/styles/' . $highlight_style . '.min.css' ); - wp_register_script( 'wp-rest-api-log-admin', plugin_dir_url( __FILE__ ) . 'js/wp-rest-api-log-admin' . $min . '.js', 'jquery', WP_REST_API_Log_Common::VERSION ); - wp_register_style( 'wp-rest-api-log-admin', plugin_dir_url( __FILE__ ) . 'css/wp-rest-api-log-admin' . $min . '.css', '', WP_REST_API_Log_Common::VERSION ); + wp_register_script( 'wp-rest-api-log-admin', WP_REST_API_LOG_URL . 'admin/js/wp-rest-api-log-admin' . $min . '.js', 'jquery', WP_REST_API_Log_Common::VERSION ); + wp_register_style( 'wp-rest-api-log-admin', WP_REST_API_LOG_URL . 'admin/css/wp-rest-api-log-admin' . $min . '.css', '', WP_REST_API_Log_Common::VERSION ); // http://trentrichardson.com/examples/timepicker/ //wp_enqueue_script( 'jquery-ui-timepicker', 'https://cdnjs.cloudflare.com/ajax/libs/jquery-ui-timepicker-addon/1.4.5/jquery-ui-timepicker-addon.min.js' ); @@ -71,18 +66,23 @@ public function register_scripts() { } - public function display_log_entry() { + static public function display_log_entry() { - include_once apply_filters( 'wp-rest-api-log-admin-view-entry-template', plugin_dir_path( __FILE__ ) .'partials/wp-rest-api-log-view-entry.php' ); + include_once apply_filters( 'wp-rest-api-log-admin-view-entry-template', WP_REST_API_LOG_PATH . 'admin/partials/wp-rest-api-log-view-entry.php' ); wp_enqueue_script( 'wp-rest-api-log-admin-highlight-js' ); wp_enqueue_style( 'wp-rest-api-log-admin-highlight-js' ); wp_enqueue_script( 'wp-rest-api-log-admin' ); - } - - public function entry_permalink( $permalink, $post ) { + /** + * Creates a permalink for a log enty. + * + * @param string $permalink Default permalink. + * @param int|WP_Post $post Post ID or object. + * @return string + */ + static public function entry_permalink( $permalink, $post ) { $post = get_post( $post ); if ( WP_REST_API_Log_DB::POST_TYPE === $post->post_type ) { $permalink = add_query_arg( array( @@ -105,7 +105,7 @@ private function plugin_name() { * @param array $query query args * @return array */ - public function wp_link_query_args( $query ) { + static public function wp_link_query_args( $query ) { if ( isset( $query['post_type' ] ) && is_array( $query['post_type'] ) ) { for ( $i = count( $query['post_type'] )-1; $i >= 0; $i-- ) { @@ -167,7 +167,43 @@ static public function add_admin_caps( $allcaps, $caps, $args ) { return $allcaps; } + /** + * Adds additional links to the row on the plugins page. + * + * @param array $actions An array of plugin action links. + * @param string $plugin_file Path to the plugin file relative to the plugins directory. + * @param array $plugin_data An array of plugin data. + * @param string $context The plugin context. Defaults are 'All', 'Active', + * 'Inactive', 'Recently Activated', 'Upgrade', + * 'Must-Use', 'Drop-ins', 'Search'. + */ + static public function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) { + + if ( is_plugin_active( $plugin_file ) && current_user_can( 'manage_options' ) ) { + + // Build the URL for the settings page. + $url = add_query_arg( + 'page', + rawurlencode( WP_REST_API_Log_Settings::$settings_page ), + admin_url( 'admin.php' ) + ); + + // Add the anchor tag to the list of plugin links. + $new_actions = array( + 'settings' => sprintf( '%2$s', + esc_url( $url ), + esc_html__( 'Settings' ) + ), + 'log' => sprintf( '%2$s', + esc_url( admin_url( 'edit.php?post_type=wp-rest-api-log' ) ), + esc_html__( 'Log' ) + ) + ); + + $actions = array_merge( $new_actions, $actions ); + } + return $actions; + } } - } diff --git a/admin/partials/wp-rest-api-log-view-entry.php b/admin/partials/wp-rest-api-log-view-entry.php index ab51a56..46e7eec 100644 --- a/admin/partials/wp-rest-api-log-view-entry.php +++ b/admin/partials/wp-rest-api-log-view-entry.php @@ -74,6 +74,7 @@
  • : status ); ?>
  • : milliseconds ) ); ?>ms
  • : response->body ) ) ); ?>
  • +
  • : user ); ?>
  • : ip_address ); ?>
  • http_x_forwarded_for ) ) : ?>
  • : http_x_forwarded_for ); ?>
  • diff --git a/assets/screenshot-1.png b/assets/screenshot-1.png index a147c12..990c393 100644 Binary files a/assets/screenshot-1.png and b/assets/screenshot-1.png differ diff --git a/assets/screenshot-2.png b/assets/screenshot-2.png new file mode 100644 index 0000000..f556601 Binary files /dev/null and b/assets/screenshot-2.png differ diff --git a/includes/class-wp-rest-api-log-common.php b/includes/class-wp-rest-api-log-common.php index 3b588e3..254df2a 100644 --- a/includes/class-wp-rest-api-log-common.php +++ b/includes/class-wp-rest-api-log-common.php @@ -7,7 +7,7 @@ class WP_REST_API_Log_Common { const PLUGIN_NAME = 'wp-rest-api-log'; - const VERSION = '2017-01-16-01'; + const VERSION = '2017-02-02-01'; const TEXT_DOMAIN = 'wp-rest-api-log'; static public function current_milliseconds() { @@ -30,6 +30,15 @@ static public function is_valid_method( $method ) { } + /** + * Outputs a taxonomy dropdown. + * + * @param string $label Label for the select element. + * @param string $all_items_prompt Prompt for "All Items". + * @param string $taxonomy Taxonomy slug. + * @param string $selected_slug Selected term slug. + * @return void. + */ static public function taxonomy_dropdown( $label, $all_items_prompt, $taxonomy, $selected_slug ) { $terms = get_terms( $taxonomy ); diff --git a/includes/class-wp-rest-api-log-db.php b/includes/class-wp-rest-api-log-db.php index 481d262..c494f93 100644 --- a/includes/class-wp-rest-api-log-db.php +++ b/includes/class-wp-rest-api-log-db.php @@ -12,6 +12,7 @@ class WP_REST_API_Log_DB { const TAXONOMY_SOURCE = 'wp-rest-api-log-source'; const POST_META_IP_ADDRESS = '_ip-address'; + const POST_META_REQUEST_USER = '_request_user'; const POST_META_HTTP_X_FORWARDED_FOR = '_http_x_forwarded_for'; const POST_META_MILLISECONDS = '_milliseconds'; const POST_META_REQUEST_BODY = '_request_body'; @@ -43,9 +44,12 @@ static private function plugin_name() { */ public function insert( $args ) { + $current_user = wp_get_current_user(); + $args = wp_parse_args( $args, array( 'time' => current_time( 'mysql' ), 'ip_address' => filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_STRING ), + 'user' => $current_user->user_login, 'http_x_forwarded_for' => filter_input( INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_SANITIZE_STRING ), 'route' => '', 'source' => 'WP REST API', @@ -133,6 +137,7 @@ private function insert_post_meta( $post_id, $args ) { $meta = array( self::POST_META_IP_ADDRESS => $args['ip_address'], + self::POST_META_REQUEST_USER => $args['user'], self::POST_META_HTTP_X_FORWARDED_FOR => $args['http_x_forwarded_for'], self::POST_META_MILLISECONDS => $args['milliseconds'], self::POST_META_REQUEST_BODY => $args['request']['body'], diff --git a/includes/class-wp-rest-api-log-entry.php b/includes/class-wp-rest-api-log-entry.php index 4a1a60c..9f7c1a3 100644 --- a/includes/class-wp-rest-api-log-entry.php +++ b/includes/class-wp-rest-api-log-entry.php @@ -39,6 +39,12 @@ static public function from_posts( array $posts ) { */ public $ip_address; + /** + * User of the request (from postmeta) + * @var string + */ + public $user; + /** * HTTP_X_FORWARDED_FOR address of the request (from postmeta) * @var string @@ -126,6 +132,7 @@ private function load_post_meta() { $post_id = $this->_post->ID; $this->ip_address = get_post_meta( $post_id, WP_REST_API_Log_DB::POST_META_IP_ADDRESS, true ); + $this->user = get_post_meta( $post_id, WP_REST_API_Log_DB::POST_META_REQUEST_USER, true ); $this->http_x_forwarded_for = get_post_meta( $post_id, WP_REST_API_Log_DB::POST_META_HTTP_X_FORWARDED_FOR, true ); $this->milliseconds = absint( get_post_meta( $post_id, WP_REST_API_Log_DB::POST_META_MILLISECONDS, true ) ); @@ -140,9 +147,20 @@ private function load_taxonomies() { } - public function get_first_term_name( $post_id, $taxonomy ) { - $terms = wp_get_post_terms( $post_id, $taxonomy, array( 'fields' => 'names' ) ); - return ! empty( $terms ) ? $terms[0] : ''; + /** + * Gets the first term name for the supplied post and taxonomy. + * + * @param int|WP_Post $post Post ID or object. + * @param string $taxonomy Taxonomy slug. + * @return string + */ + public function get_first_term_name( $post, $taxonomy ) { + + // Uses get_the_terms() since wp_get_object_terms() does not + // do any caching. + $terms = get_the_terms( $post, $taxonomy ); + + return ! empty( $terms ) && is_array( $terms ) ? $terms[0]->name : ''; } diff --git a/includes/class-wp-rest-api-log.php b/includes/class-wp-rest-api-log.php index b9ac47e..f0c0b1c 100644 --- a/includes/class-wp-rest-api-log.php +++ b/includes/class-wp-rest-api-log.php @@ -86,8 +86,11 @@ static public function log_rest_api_response( $served, $result, $request, $rest_ return $served; } + $current_user = wp_get_current_user(); + $args = array( 'ip_address' => filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_STRING ), + 'user' => $current_user->user_login, 'http_x_forwarded_for' => filter_input( INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_SANITIZE_STRING ), 'route' => $route, 'method' => $request->get_method(), diff --git a/readme.md b/readme.md index b27b53f..baaee57 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ **Donate link:** https://github.com/petenelson/wp-rest-api-log **Requires at least:** 4.4 **Tested up to:** 4.7 -**Stable tag:** 1.4.0 +**Stable tag:** 1.5.0 **License:** GPLv2 or later **License URI:** http://www.gnu.org/licenses/gpl-2.0.html @@ -31,7 +31,6 @@ Find us on [GitHub](https://github.com/petenelson/wp-rest-api-log)! Roadmap * Better search capabilities for log entries via the REST API endpoint -* WooCommerce REST API Logging ## Installation ## @@ -44,6 +43,12 @@ Roadmap ## Changelog ## +### v1.5.0 February 2, 2017 ### +* Added logging for the user making the request (props [drsdre](https://github.com/drsdre) for the pull request). +* Added Settings and Log links from the Plugins page. +* Updated term fetching when viewing log entries for fewer database queries and better performance. +* Updated highlight.js to 9.9.0 + ### v1.4.0 January 23, 2017 ### * Added the ability to filter routes for logging, either include or exclude specific routes. @@ -84,6 +89,12 @@ Roadmap ## Upgrade Notice ## +### v1.5.0 February 2, 2017 ### +* Added logging for the user making the request (props [drsdre](https://github.com/drsdre) for the pull request). +* Added Settings and Log links from the Plugins page. +* Updated term fetching when viewing log entries for fewer database queries and better performance. +* Updated highlight.js to 9.9.0 + ### v1.4.0 January 23, 2017 ### * Added the ability to filter routes for logging, either include or exclude specific routes. @@ -107,6 +118,9 @@ You can go into Settings > ElasticPress to enable logging for requests & respons ## Screenshots ## -### 1. Sample admin screen ### -![Sample admin screen](https://raw.githubusercontent.com/petenelson/wp-rest-api-log/master/assets/screenshot-1.png) +### 1. Sample list of log entries ### +![Sample list of log entries](https://raw.githubusercontent.com/petenelson/wp-rest-api-log/master/assets/screenshot-1.png) + +### 2. Sample log entry details ### +![Sample log entry details](https://raw.githubusercontent.com/petenelson/wp-rest-api-log/master/assets/screenshot-2.png) diff --git a/readme.txt b/readme.txt index 399d71e..96a361e 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: wp rest api, rest api, wp api, api, json, json api, log, logging, elasticp Donate link: https://github.com/petenelson/wp-rest-api-log Requires at least: 4.4 Tested up to: 4.7 -Stable tag: 1.4.0 +Stable tag: 1.5.0 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -27,7 +27,6 @@ Find us on [GitHub](https://github.com/petenelson/wp-rest-api-log)! Roadmap * Better search capabilities for log entries via the REST API endpoint -* WooCommerce REST API Logging == Installation == @@ -40,6 +39,12 @@ Roadmap == Changelog == += v1.5.0 February 2, 2017 = +* Added logging for the user making the request (props [drsdre](https://github.com/drsdre) for the pull request). +* Added Settings and Log links from the Plugins page. +* Updated term fetching when viewing log entries for fewer database queries and better performance. +* Updated highlight.js to 9.9.0 + = v1.4.0 January 23, 2017 = * Added the ability to filter routes for logging, either include or exclude specific routes. @@ -80,6 +85,12 @@ Roadmap == Upgrade Notice == += v1.5.0 February 2, 2017 = +* Added logging for the user making the request (props [drsdre](https://github.com/drsdre) for the pull request). +* Added Settings and Log links from the Plugins page. +* Updated term fetching when viewing log entries for fewer database queries and better performance. +* Updated highlight.js to 9.9.0 + = v1.4.0 January 23, 2017 = * Added the ability to filter routes for logging, either include or exclude specific routes. @@ -103,4 +114,5 @@ You can go into Settings > ElasticPress to enable logging for requests & respons == Screenshots == -1. Sample admin screen +1. Sample list of log entries +2. Sample log entry details diff --git a/wp-rest-api-log.php b/wp-rest-api-log.php index 463ef00..5c39fdb 100644 --- a/wp-rest-api-log.php +++ b/wp-rest-api-log.php @@ -3,7 +3,7 @@ * Plugin Name: REST API Log * Description: Logs requests and responses for the REST API * Author: Pete Nelson - * Version: 1.4.0 + * Version: 1.5.0 * Plugin URI: https://github.com/petenelson/wp-rest-api-log * Text Domain: wp-rest-api-log * Domain Path: /languages @@ -24,6 +24,10 @@ define( 'WP_REST_API_LOG_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) ); } +if ( ! defined( 'WP_REST_API_LOG_URL' ) ) { + define( 'WP_REST_API_LOG_URL', trailingslashit( plugin_dir_url( __FILE__ ) ) ); +} + if ( ! defined( 'WP_REST_API_LOG_FILE' ) ) { define( 'WP_REST_API_LOG_FILE', __FILE__ ); } @@ -110,6 +114,7 @@ WP_REST_API_Log_Post_Type::plugins_loaded(); WP_REST_API_Log_Controller::plugins_loaded(); WP_REST_API_Log_ElasticPress::plugins_loaded(); +WP_REST_API_Log_Admin::plugins_loaded(); /* Activation hook */ register_activation_hook( __FILE__, function() {