Merge pull request #12972 from woocommerce/log-handler-interface

Add log handler interface
This commit is contained in:
Mike Jolley 2017-01-25 00:42:50 +00:00 committed by GitHub
commit 0df50c59a3
5 changed files with 74 additions and 25 deletions

View File

@ -11,20 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* @category Abstract Class
* @author WooThemes
*/
abstract class WC_Log_Handler {
/**
* Handle a log entry.
*
* @param int $timestamp Log timestamp.
* @param string $level emergency|alert|critical|error|warning|notice|info|debug
* @param string $message Log message.
* @param array $context Additional information for log handlers.
*
* @return bool False if value was not handled and true if value was handled.
*/
abstract public function handle( $timestamp, $level, $message, $context );
abstract class WC_Log_Handler implements WC_Log_Handler_Interface {
/**
* Formats a timestamp for use in log messages.

View File

@ -43,6 +43,23 @@ class WC_Logger implements WC_Logger_Interface {
$handlers = apply_filters( 'woocommerce_register_log_handlers', array() );
}
$register_handlers = array();
foreach ( $handlers as $handler ) {
$implements = class_implements( $handler );
if ( is_object( $handler ) && is_array( $implements ) && in_array( 'WC_Log_Handler_Interface', $implements ) ) {
$register_handlers[] = $handler;
} else {
wc_doing_it_wrong(
__METHOD__,
sprintf(
__( 'The provided handler <code>%s</code> does not implement WC_Log_Handler_Interface.', 'woocommerce' ),
esc_html( is_object( $handler ) ? get_class( $handler ) : $handler )
),
'2.7'
);
}
}
if ( null !== $threshold ) {
$threshold = WC_Log_Levels::get_level_severity( $threshold );
} elseif ( defined( 'WC_LOG_THRESHOLD' ) && WC_Log_Levels::is_valid_level( WC_LOG_THRESHOLD ) ) {
@ -51,7 +68,7 @@ class WC_Logger implements WC_Logger_Interface {
$threshold = null;
}
$this->handlers = $handlers;
$this->handlers = $register_handlers;
$this->threshold = $threshold;
}
@ -102,9 +119,7 @@ class WC_Logger implements WC_Logger_Interface {
*/
public function log( $level, $message, $context = array() ) {
if ( ! WC_Log_Levels::is_valid_level( $level ) ) {
$class = __CLASS__;
$method = __FUNCTION__;
wc_doing_it_wrong( "{$class}::{$method}", sprintf( __( 'WC_Logger::log was called with an invalid level "%s".', 'woocommerce' ), $level ), '2.7' );
wc_doing_it_wrong( __METHOD__, sprintf( __( 'WC_Logger::log was called with an invalid level "%s".', 'woocommerce' ), $level ), '2.7' );
}
if ( $this->should_handle( $level ) ) {

View File

@ -0,0 +1,28 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC Log Handler Interface
*
* Functions that must be defined to correctly fulfill log handler API.
*
* @version 1.0.0
* @category Interface
* @author WooThemes
*/
interface WC_Log_Handler_Interface {
/**
* Handle a log entry.
*
* @param int $timestamp Log timestamp.
* @param string $level emergency|alert|critical|error|warning|notice|info|debug
* @param string $message Log message.
* @param array $context Additional information for log handlers.
*
* @return bool False if value was not handled and true if value was handled.
*/
public function handle( $timestamp, $level, $message, $context );
}

View File

@ -15,7 +15,7 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
public function test_add() {
$time = time();
$handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$handler
@ -82,19 +82,19 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
*/
public function test_log_handlers() {
$false_handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$false_handler->expects( $this->exactly( 8 ) )->method( 'handle' )->will( $this->returnValue( false ) );
$true_handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$false_handler->expects( $this->exactly( 8 ) )->method( 'handle' )->will( $this->returnValue( true ) );
$final_handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$final_handler->expects( $this->exactly( 8 ) )->method( 'handle' );
@ -159,7 +159,7 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
// Test no filtering by default
delete_option( 'woocommerce_log_threshold' );
$handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$handler
@ -192,6 +192,24 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
$log->debug( 'debug message' );
}
/**
* Test that the logger validates handlers
*
* If a handler does not implement WC_Log_Handler_Interface, WC_Logger should complain
* (wc_doing_it_wrong) and not register the handler. This handler should receive no messages.
*
* @since 2.7.0
*/
public function test_validate_handler_interface() {
$handler = $this
->getMockBuilder( 'stdClass' )
->setMethods( array( 'handle' ) )
->getMock();
$handler->expects( $this->never() )->method( 'handle' );
new WC_Logger( array( $handler ) );
$this->setExpectedIncorrectUsage( 'WC_Logger::__construct' );
}
/**
* Helper for 'woocommerce_register_log_handlers' filter test.
*
@ -204,7 +222,7 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
*/
public function return_assertion_handlers() {
$handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();
$handler->expects( $this->exactly( 8 ) )->method( 'handle' );
@ -224,7 +242,7 @@ class WC_Tests_Logger extends WC_Unit_Test_Case {
public function create_mock_handler() {
$time = time();
$handler = $this
->getMockBuilder( 'WC_Log_Handler' )
->getMockBuilder( 'WC_Log_Handler_Interface' )
->setMethods( array( 'handle' ) )
->getMock();

View File

@ -294,6 +294,7 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-product-variable-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-shipping-zone-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-logger-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-log-handler-interface.php' );
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-token.php' ); // Payment Tokens
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-product.php' ); // Products
include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-order.php' ); // Orders