File "class-kp-logger.php"
Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/klarna-payments-for-woocommerce/classes/class-kp-logger.php
File size: 6.39 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Logger class file.
*
* @package WC_Klarna_Payments/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Logger class.
*/
class KP_Logger {
/**
* Log message string
*
* @var $log
*/
public static $log;
/**
* Logs an event.
*
* @param array|string $data The data string.
*/
public static function log( $data ) {
$kp_settings = get_option( 'woocommerce_klarna_payments_settings', array() );
if ( 'no' !== $kp_settings['logging'] ) {
$message = self::format_data( $data );
if ( empty( self::$log ) ) {
self::$log = new WC_Logger();
}
self::$log->add( 'klarna_payments', wp_json_encode( $message ) );
}
if ( isset( $data['response']['code'] ) && ( $data['response']['code'] < 200 || $data['response']['code'] > 299 ) ) {
self::log_to_db( $data );
}
}
/**
* Formats the log data to prevent json error.
*
* @param array $data Json string of data.
* @return array
*/
public static function format_data( $data ) {
if ( isset( $data['request']['body'] ) ) {
$request_body = json_decode( $data['request']['body'], true );
$data['request']['body'] = $request_body;
}
return $data;
}
/**
* Formats the log data to be logged.
*
* @param string $payment_id The "Klarna Payments" Payment ID.
* @param string $method The method.
* @param string $title The title for the log.
* @param array $request_args The request args.
* @param array $response The response.
* @param string $code The status code.
* @param string $request_url The request URL for the request.
* @return array
*/
public static function format_log( $payment_id, $method, $title, $request_args, $response, $code, $request_url = null ) {
return array(
'id' => $payment_id,
'type' => $method,
'title' => $title,
'request' => $request_args,
'request_url' => $request_url,
'response' => array(
'body' => $response,
'code' => $code,
),
'timestamp' => date( 'Y-m-d H:i:s' ), // phpcs:ignore WordPress.DateTime.RestrictedFunctions -- Date is not used for display.
'stack' => self::get_stack(),
'plugin_version' => WC_KLARNA_PAYMENTS_VERSION,
);
}
/**
* Logs an event in the WP DB.
*
* @param array $data The data to be logged.
*/
public static function log_to_db( $data ) {
$logs = get_option( 'krokedil_debuglog_kp', array() );
if ( ! empty( $logs ) ) {
$logs = json_decode( $logs );
}
$logs = array_slice( $logs, -14 );
$logs[] = $data;
$logs = wp_json_encode( $logs );
update_option( 'krokedil_debuglog_kp', $logs, false );
}
/**
* Gets the stack for the request.
*
* @return array
*/
public static function get_stack() {
$debug_data = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Data is not used for display.
$stack = array();
// Skip the first 4 items in the stack trace to skip to the actual caller.
$count = count( $debug_data );
for ( $i = 5; $i < $count; $i++ ) {
self::process_debug_line( $stack, $debug_data[ $i ] );
}
return $stack;
}
/**
* Processes a debug line, and adds it to the stack trace.
*
* @param array $stack The stack trace passed by reference.
* @param array $debug_line The debug info from the raw stack trace.
* @return void
*/
private static function process_debug_line( &$stack, $debug_line ) {
$class = $debug_line['class'] ?? '';
$type = $debug_line['type'] ?? '';
$function = $debug_line['function'] ?? '';
$args = $debug_line['args'] ?? array();
self::handle_wp_hook( $class, $function, $args, $debug_line );
// Construct a caller string.
$caller = self::get_caller_string( $class, $type, $function, $args );
$row = array(
'file' => $debug_line['file'] ?? '',
'line' => $debug_line['line'] ?? '',
'function' => $caller,
);
$stack[] = $row;
}
/**
* Get the caller string from the stack trace line.
*
* @param string $class The class name.
* @param string $type The type, :: or -> depending on if its a static or non static class.
* @param string $function The function name.
* @param array $args The arguments passed to the caller.
* @return string
*/
private static function get_caller_string( $class, $type, $function, $args ) {
$log_extra_data = apply_filters( 'wc_kp_extra_debug', false );
// Construct a caller string.
$caller = $class . $type . $function;
$caller .= '(';
$caller .= $log_extra_data ? implode(
', ',
array_map(
function ( $value ) {
// Json encode all values so that we can see what objects and arrays are passed. Dont escape anything, partial output on errors, and ignore slashes and line terminators.
return wp_json_encode( $value, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_LINE_TERMINATORS | JSON_UNESCAPED_SLASHES );
},
$args
)
) : '';
$caller .= ')';
return $caller;
}
/**
* Handles any WP hooks that are called.
*
* @param string $class The class name.
* @param string $function The function name.
* @param array $args The arguments. Passed by reference to allow modifications.
* @param array $debug_line The debug line.
* @return void
*/
private static function handle_wp_hook( $class, $function, &$args, $debug_line ) {
if ( 'WP_Hook' === $class && in_array( $function, array( 'apply_filters', 'do_action' ), true ) ) {
$wp_hook = $debug_line['object'] ?? null;
if ( $wp_hook instanceof WP_Hook ) {
$priority = $wp_hook->current_priority();
$current = current( $wp_hook->current() );
$name = '';
foreach ( $current['function'] ?? array() as $function ) {
$name .= self::get_name_of_hook_function( $function );
}
array_unshift( $args, $name . ' (' . $priority . ')' );
}
}
}
/**
* Gets a string back from the object passed to match the name of any class that it is an instance off.
*
* @param mixed $object The potential class object.
* @return string
*/
private static function get_name_of_hook_function( $object ) {
// If the object is null, reutrn an empty string.
if ( null === $object ) {
return '';
}
// If its not an object, check if class exists, else return as function name.
if ( ! is_object( $object ) ) {
return $object . ( class_exists( $object ) ? '::' : '()' );
}
// Get the class name and return it with appended static divider.
return get_class( $object ) . '::';
}
}