Skip to content
Snippets Groups Projects
Select Git revision
  • 3321d39255f0a4a85531ac9556b7070f066aafe0
  • master default protected
  • feat/message-handling
  • feat/request-id
  • 1.13.2
  • 1.13.1
  • 1.13.0
  • 1.12.1
  • 1.12.0
  • 1.11.0
  • 1.11.0-beta2
  • 1.11.0-beta1
  • 1.10.2
  • 1.10.1
  • 1.10.0
  • 1.9.0
  • 1.8.0
  • 1.7.4
  • 1.7.3
  • 1.7.2
  • 1.7.1
  • 1.7.0
  • 1.6.2
  • 1.6.2-beta2
24 results

WooCommerceCapture.php

Blame
  • WooCommerceCapture.php 3.99 KiB
    <?php
    
    namespace WPDesk\Logger\WC;
    
    use Monolog\Logger;
    use WPDesk\Logger\WC\Exception\WCLoggerAlreadyCaptured;
    
    /**
     * Can capture default WooCommerce logger
     *
     * @package WPDesk\Logger
     */
    class WooCommerceCapture
    {
        const WOOCOMMERCE_LOGGER_FILTER = 'woocommerce_logging_class';
        const WOOCOMMERCE_AFTER_IS_LOADED_ACTION = 'woocommerce_loaded';
    
        /** @var string Minimal version of WooCommerce supported by logger capture */
        const SUPPORTED_WC_VERSION = '3.5.0';
    
        /**
         * Is logger filter captured by library.
         *
         * @var bool
         */
        private $isCaptured = false;
    
        /**
         * Our monolog
         *
         * @var Logger
         */
        private $monolog;
    
        /**
         * Original WC Logger
         *
         * @var \WC_Logger_Interface
         */
        private $originalWCLogger;
    
        /**
         * WordPress hook function to return our logger
         *
         * @var ?callable
         */
        private $captureHookFunction;
    
        /**
         * WordPress hook function to return original wc logger
         *
         * @var ?callable
         */
        private $freeHookFunction;
    
        public function __construct(Logger $monolog)
        {
            $this->monolog = $monolog;
        }
    
        /**
         * Prepares callable property captureHookFunction.
         * For it to work WC have to be loaded
         */
        private function prepareCaptureHookCallable()
        {
            $monolog = $this->monolog;
    
            if ($this->captureHookFunction === null) {
                $this->captureHookFunction = function () use ($monolog) {
                    return new WooCommerceMonologPlugin($monolog, $this->originalWCLogger);
                };
                $this->monolog->pushHandler(new WooCommerceHandler($this->originalWCLogger));
            }
        }
    
        /**
         * Is this version of WooCommerce is supported by logger capture
         *
         * @return bool
         */
        public static function isSupportedWCVersion()
        {
            return class_exists(\WooCommerce::class) && version_compare(\WooCommerce::instance()->version,
                    self::SUPPORTED_WC_VERSION, '>=');
        }
    
        /**
         * Capture WooCommerce logger and inject our decorated Logger
         */
        public function captureWcLogger()
        {
            if (self::isSupportedWCVersion()) {
                if ($this->isCaptured) {
                    throw new WCLoggerAlreadyCaptured('Try to free wc logger first.');
                }
    
                if ($this->isWooCommerceLoggerAvailable()) {
                    $this->prepareFreeHookCallable();
                    $this->prepareCaptureHookCallable();
    
                    remove_filter(self::WOOCOMMERCE_LOGGER_FILTER, $this->freeHookFunction);
                    add_filter(self::WOOCOMMERCE_LOGGER_FILTER, $this->captureHookFunction);
    
                    $this->isCaptured = true;
                } elseif (function_exists('add_action')) {
                    add_action(self::WOOCOMMERCE_AFTER_IS_LOADED_ACTION, [$this, 'captureWcLogger']);
                } else {
                    $this->monolog->alert('Cannot capture WC - WordPress is not available.');
                }
            } else {
                $this->monolog->alert('Cannot capture WC - WooCommerce version is not supported.');
            }
    
        }
    
        /**
         * Can i fetch WC Logger?
         *
         * @return bool
         */
        private function isWooCommerceLoggerAvailable()
        {
            return function_exists('wc_get_logger');
        }
    
        /**
         * Prepares callable property freeHookFunction.
         * For it to work WC have to be loaded
         */
        private function prepareFreeHookCallable()
        {
            if ($this->freeHookFunction === null) {
                $this->originalWCLogger = $logger = wc_get_logger();
    
                $this->freeHookFunction = function () use ($logger) {
                    return $logger;
                };
            }
        }
    
        /**
         * Remove WooCommerce logger injection
         */
        public function freeWcLogger()
        {
            if ($this->isCaptured) {
                remove_filter(self::WOOCOMMERCE_LOGGER_FILTER, $this->captureHookFunction);
                add_filter(self::WOOCOMMERCE_LOGGER_FILTER, $this->freeHookFunction);
    
                $this->isCaptured = false;
            }
        }
    }