From d6a9816893ec1f4162b2bf8a8f04aed4f0ac62a1 Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 23 Sep 2016 01:20:18 -0400 Subject: [PATCH 1/6] first pass javascript logging --- ai-logger.php | 5 ++++- includes/class-ai-logger-plugin.php | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ai-logger.php b/ai-logger.php index 7fcfc3f0..916b3646 100644 --- a/ai-logger.php +++ b/ai-logger.php @@ -21,8 +21,11 @@ exit; } +define( 'AI_LOGGER_PATH', plugin_dir_path( __FILE__ ) ); +define( 'AI_LOGGER_URL', plugins_url( '/', __FILE__ ) ); + // require the main plugin class -require_once plugin_dir_path( __FILE__ ) . 'includes/class-ai-logger-plugin.php'; +require_once AI_LOGGER_PATH . 'includes/class-ai-logger-plugin.php'; /** * Begin execution of the main plugin class diff --git a/includes/class-ai-logger-plugin.php b/includes/class-ai-logger-plugin.php index 7c71fe40..af8eef56 100644 --- a/includes/class-ai-logger-plugin.php +++ b/includes/class-ai-logger-plugin.php @@ -62,6 +62,7 @@ public function run() { require_once( $this->plugin_path . 'includes/class-ai-logger-taxonomy.php' ); require_once( $this->plugin_path . 'includes/class-ai-logger-taxonomy-context.php' ); require_once( $this->plugin_path . 'includes/class-ai-logger-taxonomy-level.php' ); + require_once( $this->plugin_path . 'includes/class-ai-logger-js.php' ); require_once( $this->plugin_path . 'includes/class-ai-logger.php' ); // hooks and filters From d11cefc91673a8541aeffed3efc3c35b342784cf Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 23 Sep 2016 01:21:20 -0400 Subject: [PATCH 2/6] adding new files for javascript logging --- includes/class-ai-logger-js.php | 72 +++++++++++++++++++++++++++++++++ static/js/logger-insert.js | 24 +++++++++++ 2 files changed, 96 insertions(+) create mode 100644 includes/class-ai-logger-js.php create mode 100644 static/js/logger-insert.js diff --git a/includes/class-ai-logger-js.php b/includes/class-ai-logger-js.php new file mode 100644 index 00000000..7c2e1f49 --- /dev/null +++ b/includes/class-ai-logger-js.php @@ -0,0 +1,72 @@ + admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'ai-logger-insert' ), + ) ); + } + + /** + * Create a log message based on posted data. + */ + public function log() { + if ( ! check_ajax_referer( 'ai-logger-insert', 'ai_logger_nonce', false ) ) { + wp_send_json_error( array( 'response' => __( 'Insecure request.', 'ai-logger' ) ) ); + } elseif ( empty( $_POST['key'] ) || empty( $_POST['message'] ) ) { + wp_send_json_error( array( 'response' => __( 'Key and message parameters are required.', 'ai-logger' ) ) ); + } + + // Sanitize input. + $key = sanitize_text_field( wp_unslash( $_POST['key'] ) ); + $message = sanitize_text_field( wp_unslash( $_POST['message'] ) ); + $clean_args = array(); + + // Clean up the arguments array. + if ( isset( $_POST['args'] ) && is_array( $_POST['args'] ) ) { + $args = wp_unslash( $_POST['args'] ); + foreach ( $args as $arg => $value ) { + $clean_args[ sanitize_text_field( $arg ) ] = sanitize_text_field( $value ); + } + } + + // Create log message. + do_action( 'ai_logger_insert', $key, $message, $clean_args ); + + // Respond. + wp_send_json_success( array( + 'response' => __( 'Log entry created.', 'ai-logger' ), + 'key' => $key, + 'message' => $message, + 'args' => $clean_args, + ) ); + } +} + +add_action( 'after_setup_theme', function() { + if ( apply_filters( 'ai_logger_enable_js_logging', true ) ) { + new AI_Logger_JS(); + } +}, 20 ); diff --git a/static/js/logger-insert.js b/static/js/logger-insert.js new file mode 100644 index 00000000..549212a3 --- /dev/null +++ b/static/js/logger-insert.js @@ -0,0 +1,24 @@ +/** + * Enable ai-logger JavaScript logging. + */ + +function aiLoggerInsert( key, message, args ) { + if ( 'object' !== typeof window.aiLogger + || 'undefined' === typeof window.aiLogger.url + || 'undefined' === typeof window.aiLogger.nonce + ) { + return false; + } + + // Args are optional. + args = args || {}; + + // Post data to the admin. + jQuery.post( window.aiLogger.url, { + 'action': 'ai_logger_insert', + 'key': key, + 'message': message, + 'args': args, + 'ai_logger_nonce': window.aiLogger.nonce, + } ); +} From 87f82045057ba6a36dd1f16bbf313ec0d3ecb616 Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 23 Sep 2016 02:30:30 -0400 Subject: [PATCH 3/6] js function documentation --- static/js/logger-insert.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/static/js/logger-insert.js b/static/js/logger-insert.js index 549212a3..0d48a9b2 100644 --- a/static/js/logger-insert.js +++ b/static/js/logger-insert.js @@ -1,7 +1,10 @@ /** * Enable ai-logger JavaScript logging. + * + * @param string Key for your log message. + * @param string Log message. + * @param object Arguments for the logger method e.g. { level: 'info', context: 'Testing', include_stack_trace: false } */ - function aiLoggerInsert( key, message, args ) { if ( 'object' !== typeof window.aiLogger || 'undefined' === typeof window.aiLogger.url From 3d20c2a1322a23b08c6cfcfc2a9dc9f5e2b19048 Mon Sep 17 00:00:00 2001 From: scott Date: Fri, 23 Sep 2016 17:29:16 -0400 Subject: [PATCH 4/6] disable js logging by default. --- includes/class-ai-logger-js.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/class-ai-logger-js.php b/includes/class-ai-logger-js.php index 7c2e1f49..a82bb1f0 100644 --- a/includes/class-ai-logger-js.php +++ b/includes/class-ai-logger-js.php @@ -1,6 +1,8 @@ Date: Thu, 10 Sep 2020 21:42:13 -0400 Subject: [PATCH 5/6] Updating the logger to allow it to be written to like an array (window.aiLogger) --- ai-logger.php | 1 + inc/bootstrap.php | 7 ++-- inc/class-ai-logger-js.php | 74 ++++++++++++++++++++++++-------------- static/js/logger-insert.js | 64 ++++++++++++++++++++------------- 4 files changed, 93 insertions(+), 53 deletions(-) diff --git a/ai-logger.php b/ai-logger.php index 97933a73..44108e2a 100644 --- a/ai-logger.php +++ b/ai-logger.php @@ -21,6 +21,7 @@ } define( 'AI_LOGGER_PATH', __DIR__ ); +define( 'AI_LOGGER_URL', plugins_url( '/', __FILE__ ) ); // Check if Composer is installed. if ( ! file_exists( __DIR__ . '/vendor/autoload.php' ) ) { diff --git a/inc/bootstrap.php b/inc/bootstrap.php index 64dd3eba..d937161a 100644 --- a/inc/bootstrap.php +++ b/inc/bootstrap.php @@ -7,8 +7,6 @@ namespace AI_Logger; -use AI_Logger_JS; - require_once __DIR__ . '/autoload.php'; try { @@ -22,6 +20,11 @@ add_action( 'after_setup_theme', function() { + /** + * Flag if Javascript logging is enabled. + * + * @param bool $enabled Flag if Javascript logging is enabled. + */ if ( apply_filters( 'ai_logger_enable_js_logging', false ) ) { new AI_Logger_JS(); } diff --git a/inc/class-ai-logger-js.php b/inc/class-ai-logger-js.php index 54ed87d8..ce62da5d 100644 --- a/inc/class-ai-logger-js.php +++ b/inc/class-ai-logger-js.php @@ -1,8 +1,16 @@ admin_url( 'admin-ajax.php' ), - 'nonce' => wp_create_nonce( 'ai-logger-insert' ), - ) ); + wp_enqueue_script( 'ai-logger-insert', AI_LOGGER_URL . '/static/js/logger-insert.js', [], '0.1', true ); + wp_localize_script( + 'ai-logger-insert', + 'aiLoggerConfig', + [ + 'nonce' => wp_create_nonce( 'ai-logger-insert' ), + 'url' => admin_url( 'admin-ajax.php' ), + ] + ); } /** @@ -36,33 +48,41 @@ public function enqueue() { */ public function log() { if ( ! check_ajax_referer( 'ai-logger-insert', 'ai_logger_nonce', false ) ) { - wp_send_json_error( array( 'response' => __( 'Insecure request.', 'ai-logger' ) ) ); - } elseif ( empty( $_POST['key'] ) || empty( $_POST['message'] ) ) { - wp_send_json_error( array( 'response' => __( 'Key and message parameters are required.', 'ai-logger' ) ) ); + wp_send_json_error( [ 'response' => __( 'Insecure request.', 'ai-logger' ) ] ); + } elseif ( empty( $_POST['message'] ) ) { + wp_send_json_error( [ 'response' => __( 'Key and message parameters are required.', 'ai-logger' ) ] ); } // Sanitize input. - $key = sanitize_text_field( wp_unslash( $_POST['key'] ) ); - $message = sanitize_text_field( wp_unslash( $_POST['message'] ) ); - $clean_args = array(); + $message = sanitize_text_field( wp_unslash( $_POST['message'] ) ); + $clean_args = []; // Clean up the arguments array. - if ( isset( $_POST['args'] ) && is_array( $_POST['args'] ) ) { + if ( isset( $_POST['args'] ) ) { $args = wp_unslash( $_POST['args'] ); + if ( is_string( $args ) ) { + $args = json_decode( $args, true ); + } + foreach ( $args as $arg => $value ) { $clean_args[ sanitize_text_field( $arg ) ] = sanitize_text_field( $value ); } } - // Create log message. - do_action( 'ai_logger_insert', $key, $message, $clean_args ); + // Setup some default arguments. + $level = $args['level'] ?? 'info'; + $args['context'] = $args['context'] ?? 'front-end'; + + // Create the log entry. + ai_logger()->$level( $message, $args ); // Respond. - wp_send_json_success( array( - 'response' => __( 'Log entry created.', 'ai-logger' ), - 'key' => $key, - 'message' => $message, - 'args' => $clean_args, - ) ); + wp_send_json_success( + [ + 'args' => $clean_args, + 'message' => $message, + 'response' => __( 'Log entry created.', 'ai-logger' ), + ] + ); } } diff --git a/static/js/logger-insert.js b/static/js/logger-insert.js index 0d48a9b2..cbad4c05 100644 --- a/static/js/logger-insert.js +++ b/static/js/logger-insert.js @@ -1,27 +1,43 @@ -/** - * Enable ai-logger JavaScript logging. - * - * @param string Key for your log message. - * @param string Log message. - * @param object Arguments for the logger method e.g. { level: 'info', context: 'Testing', include_stack_trace: false } - */ -function aiLoggerInsert( key, message, args ) { - if ( 'object' !== typeof window.aiLogger - || 'undefined' === typeof window.aiLogger.url - || 'undefined' === typeof window.aiLogger.nonce - ) { - return false; - } - // Args are optional. - args = args || {}; +window.aiLogger = window.aiLogger || []; - // Post data to the admin. - jQuery.post( window.aiLogger.url, { - 'action': 'ai_logger_insert', - 'key': key, - 'message': message, - 'args': args, - 'ai_logger_nonce': window.aiLogger.nonce, - } ); +class Logger { + /** + * Constructor. + * + * @param {...any} args Array of arguments from `window.aiLogger`. + */ + constructor(...args) { + console.log('args', args); + if (args.length) { + args.forEach((item) => this.push(...item)) + } + } + + /** + * Handle a log event. + * + * @param {Array} record Log record. + */ + async push(...args) { + const [ message, logArgs ] = args; + const { nonce, url } = window.aiLoggerConfig; + + // Include the current request information. + logArgs.url = window.location.href; + + const body = new URLSearchParams(); + body.append('action', 'ai_logger_insert'); + body.append('ai_logger_nonce', nonce); + body.append('args', JSON.stringify(logArgs)); + body.append('message', message); + + await fetch(url, { + method: 'POST', + credentials: 'same-origin', + body, + }); + } } + +window.aiLogger = new Logger(...window.aiLogger || []); From d0ad828fd9a7fb8257a75af58fdc1f8b404c0afe Mon Sep 17 00:00:00 2001 From: Sean Fisher Date: Thu, 10 Sep 2020 21:42:34 -0400 Subject: [PATCH 6/6] Remove the console --- static/js/logger-insert.js | 1 - 1 file changed, 1 deletion(-) diff --git a/static/js/logger-insert.js b/static/js/logger-insert.js index cbad4c05..8a0c00fa 100644 --- a/static/js/logger-insert.js +++ b/static/js/logger-insert.js @@ -8,7 +8,6 @@ class Logger { * @param {...any} args Array of arguments from `window.aiLogger`. */ constructor(...args) { - console.log('args', args); if (args.length) { args.forEach((item) => this.push(...item)) }