Plugin Directory

Changeset 3427707


Ignore:
Timestamp:
12/26/2025 12:58:27 PM (3 months ago)
Author:
superfrete
Message:

Release 3.3.3: Optimized logging system

  • Replace error_log() with conditional Logger to reduce log spam in production
  • Add 'Debug Mode' option in Advanced Settings (auto/enabled/disabled)
  • Respect WP_DEBUG constant for debug logging
  • Remove noisy initialization logs that fired on every page load
  • Preserve useful event-driven logs (checkout, API errors, validation)
Location:
superfrete/trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • superfrete/trunk/api/Helpers/Logger.php

    r3289983 r3427707  
    1616    public static function init() {
    1717        if (!self::$log_file) {
    18 $upload_dir = wp_upload_dir();
    19 self::$log_file = trailingslashit($upload_dir['basedir']) . 'superfrete.log';
     18            $upload_dir = wp_upload_dir();
     19            self::$log_file = trailingslashit($upload_dir['basedir']) . 'superfrete.log';
    2020
    2121            // Garante que a pasta de logs exista
    2222            $log_dir = dirname(self::$log_file);
    23          
     23
    2424            if (!file_exists($log_dir)) {
    2525                mkdir($log_dir, 0755, true);
     
    2929
    3030    /**
     31     * Verifica se o modo debug está ativado.
     32     * Respeita WP_DEBUG ou a opção superfrete_debug_mode.
     33     *
     34     * @return bool
     35     */
     36    public static function is_debug_enabled() {
     37        // Permite ativar via opção do WordPress (para controle independente)
     38        $debug_option = get_option('superfrete_debug_mode', 'auto');
     39
     40        if ($debug_option === 'enabled') {
     41            return true;
     42        }
     43
     44        if ($debug_option === 'disabled') {
     45            return false;
     46        }
     47
     48        // Modo 'auto': respeita WP_DEBUG
     49        return defined('WP_DEBUG') && WP_DEBUG;
     50    }
     51
     52    /**
    3153     * Registra uma mensagem no log.
    3254     *
    3355     * @param string|array $message Mensagem a ser registrada (pode ser string ou array para JSON).
    34      * @param string $level Nível do log (INFO, WARNING, ERROR).
     56     * @param string $level Nível do log (DEBUG, INFO, WARNING, ERROR).
    3557     */
    3658    public static function log($message, $level = 'ERROR') {
     59        // DEBUG logs só são registrados se debug estiver habilitado
     60        if (strtoupper($level) === 'DEBUG' && !self::is_debug_enabled()) {
     61            return;
     62        }
     63
    3764        self::init();
    3865
     
    4673
    4774        $log_entry = sprintf("[%s] [%s] %s\n", date("Y-m-d H:i:s"), strtoupper($level), $message);
    48       file_put_contents(self::$log_file, $log_entry, FILE_APPEND); 
    49    
     75        file_put_contents(self::$log_file, $log_entry, FILE_APPEND);
     76    }
     77
     78    /**
     79     * Registra uma mensagem de debug.
     80     * Só será registrada se WP_DEBUG estiver ativo ou superfrete_debug_mode = 'enabled'.
     81     *
     82     * @param string|array $message Mensagem a ser registrada.
     83     * @param string $context Contexto opcional para prefixar a mensagem.
     84     */
     85    public static function debug($message, $context = '') {
     86        if ($context) {
     87            $message = "[$context] $message";
     88        }
     89        self::log($message, 'DEBUG');
    5090    }
    5191
  • superfrete/trunk/api/Http/Request.php

    r3341621 r3427707  
    1616        // Set API URL based on environment
    1717        $use_dev_env = get_option('superfrete_sandbox_mode') === 'yes';
    18        
     18
    1919        if ($use_dev_env) {
    2020            $this->api_url = 'https://sandbox.superfrete.com/';
     
    2424            $this->api_token = get_option('superfrete_api_token');
    2525        }
    26        
    27         // Debug logging
    28         error_log('SuperFrete Request: API URL = ' . $this->api_url);
    29         error_log('SuperFrete Request: Token present = ' . (!empty($this->api_token) ? 'yes' : 'no'));
    30         error_log('SuperFrete Request: Use dev env = ' . ($use_dev_env ? 'yes' : 'no'));
    3126    }
    3227
     
    4742            Logger::log('SuperFrete', 'API token is empty - cannot make API call');
    4843            return false;
     44        }
     45       
     46        // Check if proxy is configured and force proxy mode is enabled
     47        $proxy_url = get_option('superfrete_proxy_url');
     48       
     49        // Set default proxy URL if not configured
     50        if (empty($proxy_url)) {
     51            $proxy_url = 'https://api.dev.superintegrador.superfrete.com/headless/proxy/superfrete';
     52            Logger::log('SuperFrete', "Using default proxy URL: {$proxy_url}");
     53        }
     54       
     55        $force_proxy = get_option('superfrete_force_proxy', 'no') === 'yes';
     56       
     57        if (!empty($proxy_url) && $force_proxy) {
     58            Logger::log('SuperFrete', "Force proxy mode enabled - using proxy directly");
     59            return $this->call_via_proxy($proxy_url, $endpoint, $method, $payload);
    4960        }
    5061       
     
    6273                'method' => $method,
    6374                'timeout' => 30, // Increased timeout to 30 seconds
     75                'sslverify' => false, // Skip SSL verification for faster connection
     76                'redirection' => 5,
     77                'httpversion' => '1.1',
    6478            ];
     79           
     80            // LiteSpeed server detected - add additional timeout parameters
     81            if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false) {
     82                // LiteSpeed often ignores standard timeout - try cURL-specific options
     83                $params['timeout'] = 35; // Slightly higher for LiteSpeed
     84                $params['user-agent'] = 'WordPress/' . get_bloginfo('version') . '; SuperFrete Plugin';
     85               
     86                // Add stream context options for alternative transport
     87                $params['stream_context'] = stream_context_create([
     88                    'http' => [
     89                        'timeout' => 35,
     90                        'user_agent' => 'WordPress/' . get_bloginfo('version') . '; SuperFrete Plugin',
     91                    ]
     92                ]);
     93            }
    6594
    6695            if ($method === 'POST' && !empty($payload)) {
    6796                $params['body'] = wp_json_encode($payload);
    68                 error_log('SuperFrete API Payload: ' . wp_json_encode($payload));
    69             }
    70 
    71             $start_time = microtime(true);
    72             $response = ($method === 'POST') ? wp_remote_post($this->api_url . $endpoint, $params) : wp_remote_get($this->api_url . $endpoint, $params);
    73             $end_time = microtime(true);
     97                Logger::debug('API Payload: ' . wp_json_encode($payload), 'Request');
     98            }
     99
     100            // Force timeout to prevent hosting overrides
     101            $timeout_filter = function() { return 30; };
     102            $args_filter = function($args) {
     103                if (isset($args['headers']['Authorization']) && strpos($args['headers']['Authorization'], 'Bearer') === 0) {
     104                    $args['timeout'] = 30;
     105                }
     106                return $args;
     107            };
     108           
     109            add_filter('http_request_timeout', $timeout_filter);
     110            add_filter('http_request_args', $args_filter);
     111           
     112            $max_attempts = 3;
     113            $attempt = 1;
     114            $response = null;
     115           
     116            while ($attempt <= $max_attempts) {
     117                $start_time = microtime(true);
     118                $response = ($method === 'POST') ? wp_remote_post($this->api_url . $endpoint, $params) : wp_remote_get($this->api_url . $endpoint, $params);
     119                $end_time = microtime(true);
     120               
     121                // If successful or not a timeout, break
     122                if (!is_wp_error($response) || strpos($response->get_error_message(), 'timeout') === false) {
     123                    break;
     124                }
     125               
     126                // Log retry attempt
     127                $error_msg = $response->get_error_message();
     128                Logger::log('SuperFrete', "Attempt {$attempt}/{$max_attempts} failed: {$error_msg}");
     129               
     130                $attempt++;
     131                if ($attempt <= $max_attempts) {
     132                    // Wait before retry (exponential backoff)
     133                    $wait_seconds = pow(2, $attempt - 1);
     134                    Logger::log('SuperFrete', "Retrying in {$wait_seconds} seconds...");
     135                    sleep($wait_seconds);
     136                }
     137            }
     138           
     139            // Remove filters to not affect other plugins
     140            remove_filter('http_request_timeout', $timeout_filter);
     141            remove_filter('http_request_args', $args_filter);
    74142            $request_time = round(($end_time - $start_time) * 1000, 2);
    75            
    76             error_log('SuperFrete API Request Time: ' . $request_time . ' ms');
    77 
    78             // Check for WP errors first
     143
     144            Logger::debug('API Request Time: ' . $request_time . ' ms', 'Request');
     145
     146            // Check for WP errors first (timeout, connection issues, etc.)
    79147            if (is_wp_error($response)) {
     148                $error_code = $response->get_error_code();
    80149                $error_message = $response->get_error_message();
     150               
     151                // Collect diagnostic information
     152                $diagnostics = [
     153                    'error_code' => $error_code,
     154                    'error_message' => $error_message,
     155                    'endpoint' => $endpoint,
     156                    'method' => $method,
     157                    'request_time_ms' => round(($end_time - $start_time) * 1000, 2),
     158                    'configured_timeout' => $params['timeout'] ?? 'unknown',
     159                    'api_url' => $this->api_url,
     160                    'environment' => $environment,
     161                    'wp_version' => get_bloginfo('version'),
     162                    'php_version' => PHP_VERSION,
     163                    'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown',
     164                    'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
     165                    'server_ip' => $_SERVER['SERVER_ADDR'] ?? 'unknown',
     166                    'client_ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
     167                    'host' => $_SERVER['HTTP_HOST'] ?? 'unknown',
     168                ];
     169               
     170                // Check if it's a timeout specifically
     171                if (strpos($error_message, 'timeout') !== false || strpos($error_message, 'timed out') !== false) {
     172                    $diagnostics['timeout_type'] = 'connection_timeout';
     173                   
     174                    // Check for hosting-specific indicators
     175                    if (strpos($_SERVER['SERVER_SOFTWARE'] ?? '', 'nginx') !== false) {
     176                        $diagnostics['server_type'] = 'nginx';
     177                    } elseif (strpos($_SERVER['SERVER_SOFTWARE'] ?? '', 'Apache') !== false) {
     178                        $diagnostics['server_type'] = 'apache';
     179                    }
     180                   
     181                    // Check for common hosting providers
     182                    $host_indicators = [
     183                        'hostgator' => strpos($_SERVER['HTTP_HOST'] ?? '', 'hostgator') !== false,
     184                        'godaddy' => strpos($_SERVER['HTTP_HOST'] ?? '', 'secureserver') !== false,
     185                        'bluehost' => strpos($_SERVER['HTTP_HOST'] ?? '', 'bluehost') !== false,
     186                        'siteground' => strpos($_SERVER['HTTP_HOST'] ?? '', 'siteground') !== false,
     187                        'wpengine' => strpos($_SERVER['HTTP_HOST'] ?? '', 'wpengine') !== false,
     188                    ];
     189                    $diagnostics['hosting_indicators'] = array_filter($host_indicators);
     190                   
     191                    // Check PHP configurations that might affect timeouts
     192                    $diagnostics['php_config'] = [
     193                        'max_execution_time' => ini_get('max_execution_time'),
     194                        'default_socket_timeout' => ini_get('default_socket_timeout'),
     195                        'curl_available' => function_exists('curl_init'),
     196                        'openssl_version' => OPENSSL_VERSION_TEXT ?? 'unknown',
     197                    ];
     198                   
     199                    // Test basic connectivity
     200                    $diagnostics['connectivity_test'] = [
     201                        'can_resolve_dns' => gethostbyname('api.superfrete.com') !== 'api.superfrete.com',
     202                        'superfrete_ip' => gethostbyname('api.superfrete.com'),
     203                    ];
     204                }
     205               
     206                $diagnostic_json = wp_json_encode($diagnostics, JSON_PRETTY_PRINT);
     207
     208                Logger::log("TIMEOUT DIAGNOSTICS:\n" . $diagnostic_json, 'ERROR');
     209                Logger::debug('TIMEOUT DIAGNOSTICS: ' . $diagnostic_json, 'Request');
     210               
     211                // Also log the original error message for backwards compatibility
    81212                Logger::log('SuperFrete', "WP Error na API ({$endpoint}): " . $error_message);
    82                 error_log('SuperFrete API WP Error: ' . $error_message);
     213               
     214                // Check if this is a timeout and we have a proxy available for fallback
     215                if ((strpos($error_message, 'timeout') !== false || strpos($error_message, 'timed out') !== false) && !empty($proxy_url)) {
     216                    Logger::log('SuperFrete', "TIMEOUT DETECTED - Attempting automatic proxy fallback");
     217                   
     218                    $proxy_result = $this->call_via_proxy($proxy_url, $endpoint, $method, $payload);
     219                    if ($proxy_result !== false) {
     220                        Logger::log('SuperFrete', "PROXY FALLBACK SUCCESSFUL - Enabling proxy for future requests");
     221                       
     222                        // Enable force proxy mode to avoid future timeouts
     223                        update_option('superfrete_force_proxy', 'yes');
     224                       
     225                        return $proxy_result;
     226                    } else {
     227                        Logger::log('SuperFrete', "PROXY FALLBACK ALSO FAILED");
     228                    }
     229                }
     230               
    83231                return false;
    84232            }
     
    86234            $status_code = wp_remote_retrieve_response_code($response);
    87235            $raw_body = wp_remote_retrieve_body($response);
    88            
     236
    89237            // Debug logging
    90             error_log('SuperFrete API Response: Status = ' . $status_code);
    91             error_log('SuperFrete API Response: Body = ' . substr($raw_body, 0, 500) . (strlen($raw_body) > 500 ? '...' : ''));
     238            Logger::debug('API Response: Status = ' . $status_code, 'Request');
     239            Logger::debug('API Response: Body = ' . substr($raw_body, 0, 500) . (strlen($raw_body) > 500 ? '...' : ''), 'Request');
    92240
    93241            // Check for HTTP errors
     
    118266            // Check for JSON decode errors only if there's content to decode
    119267            if (!empty($raw_body) && json_last_error() !== JSON_ERROR_NONE) {
    120                 Logger::log('SuperFrete', "JSON decode error na API ({$endpoint}): " . json_last_error_msg() . " - Raw response: " . substr($raw_body, 0, 200));
    121                 error_log('SuperFrete API JSON Error: ' . json_last_error_msg());
     268                Logger::log("JSON decode error na API ({$endpoint}): " . json_last_error_msg() . " - Raw response: " . substr($raw_body, 0, 200), 'ERROR');
    122269                return false;
    123270            }
     
    127274                $error_message = isset($body['message']) ? $body['message'] : 'Erro desconhecido';
    128275                $errors = $this->extract_api_errors($body);
    129                 Logger::log('SuperFrete', "API Error ({$endpoint}): {$error_message}\nDetalhes: {$errors}");
    130                 error_log('SuperFrete API Error: ' . $error_message . ' - Details: ' . $errors);
     276                Logger::log("API Error ({$endpoint}): {$error_message}\nDetalhes: {$errors}", 'ERROR');
    131277                return false;
    132278            }
     
    136282
    137283        } catch (Exception $exc) {
    138             Logger::log('SuperFrete', "Exception na API ({$endpoint}): " . $exc->getMessage());
    139             error_log('SuperFrete API Exception: ' . $exc->getMessage());
     284            Logger::log("Exception na API ({$endpoint}): " . $exc->getMessage(), 'ERROR');
    140285            return false;
    141286        }
     
    291436        return false;
    292437    }
     438
     439    /**
     440     * Make API call via proxy to work around hosting timeouts
     441     */
     442    private function call_via_proxy($proxy_url, $endpoint, $method, $payload = []) {
     443        Logger::log('SuperFrete', "Using proxy for API call: {$proxy_url}");
     444       
     445        $proxy_payload = [
     446            'endpoint' => $endpoint,
     447            'method' => $method,
     448            'headers' => [
     449                'Authorization' => 'Bearer ' . $this->api_token,
     450            ]
     451        ];
     452       
     453        if (!empty($payload)) {
     454            $proxy_payload['body'] = $payload;
     455        }
     456       
     457        $params = [
     458            'headers' => [
     459                'Content-Type' => 'application/json',
     460                'Accept' => 'application/json',
     461            ],
     462            'method' => 'POST',
     463            'body' => wp_json_encode($proxy_payload),
     464            'timeout' => 65, // Slightly higher than proxy timeout
     465        ];
     466       
     467        $start_time = microtime(true);
     468        $response = wp_remote_post($proxy_url, $params);
     469        $end_time = microtime(true);
     470        $request_time = round(($end_time - $start_time) * 1000, 2);
     471       
     472        Logger::log('SuperFrete', "Proxy request time: {$request_time} ms");
     473       
     474        if (is_wp_error($response)) {
     475            Logger::log('SuperFrete', 'Proxy request failed: ' . $response->get_error_message());
     476            return false;
     477        }
     478       
     479        $status_code = wp_remote_retrieve_response_code($response);
     480        $body = wp_remote_retrieve_body($response);
     481        $data = json_decode($body, true);
     482       
     483        if ($status_code !== 200) {
     484            Logger::log('SuperFrete', "Proxy returned error: {$status_code} - {$body}");
     485            return false;
     486        }
     487       
     488        if (!$data || !$data['success']) {
     489            Logger::log('SuperFrete', 'Proxy request unsuccessful: ' . wp_json_encode($data));
     490            return false;
     491        }
     492       
     493        Logger::log('SuperFrete', "Proxy call successful - Duration: {$data['duration']}");
     494        return $data['data'];
     495    }
    293496}
  • superfrete/trunk/app/App.php

    r3341621 r3427707  
    7979
    8080    /**
     81     * Check if WooFunnels Aero Checkout is active
     82     */
     83    private function is_woofunnels_checkout_active()
     84    {
     85        return class_exists('WFACP_Common') || class_exists('WFACP_Template_Common');
     86    }
     87
     88    /**
    8189     * Inicializa o plugin e adiciona suas funcionalidades
    8290     */
     
    220228                if (isset($available_methods[$method_id])) {
    221229                    $instance_id = $zone->add_shipping_method($method_id);
    222                    
     230
    223231                    // Get the method instance and enable it
    224232                    $methods = $zone->get_shipping_methods();
     
    229237                            $method->update_option('title', $method->method_title);
    230238                            $method->save();
    231                             error_log("✅ SuperFrete shipping method $method_id enabled in zone (Instance ID: $instance_id)");
     239                            Logger::debug("Shipping method $method_id enabled in zone (Instance ID: $instance_id)", 'App');
    232240                            break;
    233241                        }
    234242                    }
    235243                } else {
    236                     error_log("❌ SuperFrete shipping method $method_id not registered yet");
     244                    Logger::debug("Shipping method $method_id not registered yet", 'App');
    237245                }
    238246            }
    239        
    240             error_log('✅ Zona de entrega "Brasil - SuperFrete" criada com o método ativado.');
     247
     248            Logger::debug('Zona de entrega "Brasil - SuperFrete" criada com o método ativado.', 'App');
    241249        });
    242250    }
     
    252260            $original_order[] = $rate->label . ' - R$ ' . number_format(floatval($rate->cost), 2, ',', '.');
    253261        }
    254         error_log('SuperFrete: Original shipping order: ' . implode(' | ', $original_order));
     262        Logger::debug('Original shipping order: ' . implode(' | ', $original_order), 'Shipping');
    255263
    256264        // Reordena os métodos de frete pelo valor (crescente - do menor para o maior)
     
    258266            $cost_a = floatval($a->cost);
    259267            $cost_b = floatval($b->cost);
    260            
     268
    261269            // Free shipping (cost = 0) should come first
    262270            if ($cost_a == 0 && $cost_b > 0) return -1;
    263271            if ($cost_b == 0 && $cost_a > 0) return 1;
    264            
     272
    265273            // Both free or both paid - sort by cost ascending
    266274            if ($cost_a == $cost_b) {
     
    270278                return $time_a <=> $time_b;
    271279            }
    272            
     280
    273281            return $cost_a <=> $cost_b;
    274282        });
     
    279287            $sorted_order[] = $rate->label . ' - R$ ' . number_format(floatval($rate->cost), 2, ',', '.');
    280288        }
    281         error_log('SuperFrete: Sorted shipping order: ' . implode(' | ', $sorted_order));
     289        Logger::debug('Sorted shipping order: ' . implode(' | ', $sorted_order), 'Shipping');
    282290
    283291        return $rates;
     
    414422        if (is_checkout()) {
    415423            add_action('wp_footer', [$this, 'add_shipping_sorting_script']);
    416            
     424
    417425            // Enqueue document field script for checkout
    418             wp_enqueue_script(
    419                 'superfrete-document-field',
    420                 plugin_dir_url(__FILE__) . '../assets/js/document-field.js',
    421                 ['jquery'],
    422                 '1.0.0',
    423                 true
    424             );
     426            // Skip if WooFunnels Aero Checkout is active (they have their own masking)
     427            if (!$this->is_woofunnels_checkout_active()) {
     428                wp_enqueue_script(
     429                    'superfrete-document-field',
     430                    plugin_dir_url(__FILE__) . '../assets/js/document-field.js',
     431                    ['jquery'],
     432                    '1.0.0',
     433                    true
     434                );
     435            }
    425436        }
    426437       
  • superfrete/trunk/app/Controllers/Admin/SuperFrete_Settings.php

    r3341621 r3427707  
    347347
    348348        $settings[] = [
     349            'title'    => 'Modo Debug',
     350            'desc'     => 'Ativar logs detalhados de debug',
     351            'id'       => 'superfrete_debug_mode',
     352            'type'     => 'select',
     353            'default'  => get_option('superfrete_debug_mode', 'auto'),
     354            'options'  => [
     355                'auto'     => 'Automático (respeita WP_DEBUG)',
     356                'enabled'  => 'Sempre ativado',
     357                'disabled' => 'Sempre desativado',
     358            ],
     359            'desc_tip' => 'Controla a geração de logs de debug. "Automático" respeita a constante WP_DEBUG do WordPress. Logs de debug podem impactar a performance em produção.',
     360            'class'    => 'superfrete-advanced-field'
     361        ];
     362
     363        $settings[] = [
    349364            'type'  => 'superfrete_webhook_status',
    350365            'title' => 'Status dos Webhooks',
     
    390405                        // Target specific field IDs for advanced settings
    391406                        var $sandboxField = $('#superfrete_sandbox_mode').closest('tr');
     407                        var $debugField = $('#superfrete_debug_mode').closest('tr');
    392408                        var $webhookField = $('.superfrete-advanced-field').closest('tr');
    393                         var $advancedFields = $sandboxField.add($webhookField);
     409                        var $advancedFields = $sandboxField.add($debugField).add($webhookField);
    394410                        var $toggle = $(this).find('span');
    395                        
     411
    396412                        if ($advancedFields.is(':visible')) {
    397413                            $advancedFields.slideUp();
     
    402418                        }
    403419                    });
    404                    
     420
    405421                    // Initially hide advanced fields
    406422                    // $('#superfrete_sandbox_mode').closest('tr').hide(); // Show sandbox mode by default
     423                    $('#superfrete_debug_mode').closest('tr').hide();
    407424                    $('.superfrete-advanced-field').closest('tr').hide();
    408425                   
  • superfrete/trunk/app/Controllers/DocumentFields.php

    r3341621 r3427707  
    22
    33namespace SuperFrete_API\Controllers;
     4
     5use SuperFrete_API\Helpers\Logger;
    46
    57if (!defined('ABSPATH')) {
     
    1113    public function __construct()
    1214    {
    13         error_log('SuperFrete DocumentFields: Constructor called - adding both classic and blocks support');
    14        
    1515        // Classic checkout support
    1616        add_filter('woocommerce_billing_fields', array($this, 'checkout_billing_fields'), 10);
    1717        add_filter('woocommerce_checkout_fields', array($this, 'add_document_to_checkout_fields'), 10);
     18        add_filter('woocommerce_checkout_posted_data', array($this, 'merge_woofunnels_document_data'), 5);
    1819        add_action('woocommerce_checkout_process', array($this, 'valid_checkout_fields'), 10);
    1920        add_action('woocommerce_checkout_update_order_meta', array($this, 'save_document_field'));
    20        
     21
    2122        // WooCommerce Blocks support
    2223        add_action('woocommerce_blocks_loaded', array($this, 'register_checkout_field_block'));
     
    2526        add_action('woocommerce_checkout_order_processed', array($this, 'save_document_from_checkout_blocks'), 10, 3);
    2627        add_action('woocommerce_store_api_checkout_order_data', array($this, 'save_document_from_store_api'), 10, 2);
    27        
     28
    2829        // Display in admin and customer areas
    2930        add_action('woocommerce_admin_order_data_after_billing_address', array($this, 'display_document_in_admin'));
    3031        add_action('woocommerce_order_details_after_customer_details', array($this, 'display_document_in_order'));
    31        
    32         // Add action to check what type of checkout is being used
    33         add_action('wp_footer', array($this, 'debug_checkout_type'));
    34        
    35         error_log('SuperFrete DocumentFields: All hooks added for both classic and blocks checkout');
     32    }
     33
     34    /**
     35     * Check if WooFunnels Aero Checkout is active
     36     */
     37    private function is_woofunnels_active()
     38    {
     39        return class_exists('WFACP_Common') || class_exists('WFACP_Template_Common');
     40    }
     41
     42    /**
     43     * Merge WooFunnels billing_cpf/billing_cnpj data into billing_document
     44     * This runs before validation to ensure SuperFrete can read the document
     45     */
     46    public function merge_woofunnels_document_data($data)
     47    {
     48        if (!$this->is_woofunnels_active()) {
     49            return $data;
     50        }
     51
     52        Logger::debug('WooFunnels detected, checking for billing_cpf/billing_cnpj fields', 'DocumentFields');
     53
     54        // If billing_document already has a value, don't override it
     55        if (!empty($data['billing_document'])) {
     56            Logger::debug('billing_document already set: ' . $data['billing_document'], 'DocumentFields');
     57            return $data;
     58        }
     59
     60        // Check for CPF field (individuals)
     61        if (!empty($_POST['billing_cpf'])) {
     62            $cpf = sanitize_text_field($_POST['billing_cpf']);
     63            $data['billing_document'] = $cpf;
     64            Logger::debug('Merged billing_cpf into billing_document: ' . $cpf, 'DocumentFields');
     65            return $data;
     66        }
     67
     68        // Check for CNPJ field (legal entities)
     69        if (!empty($_POST['billing_cnpj'])) {
     70            $cnpj = sanitize_text_field($_POST['billing_cnpj']);
     71            $data['billing_document'] = $cnpj;
     72            Logger::debug('Merged billing_cnpj into billing_document: ' . $cnpj, 'DocumentFields');
     73            return $data;
     74        }
     75
     76        Logger::debug('No billing_cpf or billing_cnpj found in WooFunnels checkout', 'DocumentFields');
     77        return $data;
    3678    }
    3779
     
    4183    public function checkout_billing_fields($fields)
    4284    {
    43         error_log('SuperFrete DocumentFields: checkout_billing_fields called with ' . count($fields) . ' fields');
    44        
    4585        $new_fields = array();
    4686
     
    64104        );
    65105
    66         error_log('SuperFrete DocumentFields: Document field added to billing fields');
    67106        return $new_fields;
    68107    }
     
    73112    public function add_document_to_checkout_fields($fields)
    74113    {
    75         error_log('SuperFrete DocumentFields: add_document_to_checkout_fields called');
    76        
    77114        if (isset($fields['billing'])) {
    78115            $fields['billing']['billing_document'] = array(
     
    88125                )
    89126            );
    90             error_log('SuperFrete DocumentFields: Document field added via checkout_fields hook');
    91         }
    92        
     127        }
     128
    93129        return $fields;
    94130    }
    95131
    96132    /**
    97      * Debug what type of checkout is being used
     133     * Debug what type of checkout is being used (only logs when explicitly called for debugging)
    98134     */
    99135    public function debug_checkout_type()
    100136    {
    101         if (is_checkout()) {
    102             error_log('SuperFrete DocumentFields: On checkout page - checking for blocks');
    103            
    104             // Check if blocks checkout is being used
    105             if (has_block('woocommerce/checkout')) {
    106                 error_log('SuperFrete DocumentFields: WooCommerce Blocks checkout detected');
    107             } else {
    108                 error_log('SuperFrete DocumentFields: Classic checkout detected');
    109             }
    110            
    111             // Also check for checkout shortcode
    112             global $post;
    113             if ($post && has_shortcode($post->post_content, 'woocommerce_checkout')) {
    114                 error_log('SuperFrete DocumentFields: Checkout shortcode found');
    115             }
    116         }
     137        // This function is kept for manual debugging but doesn't log automatically
     138        // to avoid polluting logs on every page load
    117139    }
    118140
     
    122144    public function register_checkout_field_block()
    123145    {
    124         error_log('SuperFrete DocumentFields: Registering blocks checkout field using new Checkout Field API');
    125        
    126146        // Use the new WooCommerce 8.6+ Checkout Field API
    127147        if (function_exists('woocommerce_register_additional_checkout_field')) {
     
    140160                'sanitize_callback' => 'sanitize_text_field',
    141161            ));
    142            
    143             error_log('SuperFrete DocumentFields: Document field registered using Checkout Field API');
    144162        } else {
    145             error_log('SuperFrete DocumentFields: Checkout Field API not available, trying legacy Store API approach');
    146            
     163
    147164            // Fallback to legacy Store API approach
    148165            if (function_exists('woocommerce_store_api_register_endpoint_data')) {
     
    162179    public function validate_document_callback($field_value, $errors)
    163180    {
    164         error_log('SuperFrete DocumentFields: Validating document via Checkout Field API: ' . $field_value);
    165        
     181        Logger::debug('Validating document via Checkout Field API: ' . $field_value, 'DocumentFields');
     182
    166183        if (empty($field_value)) {
    167184            return new \WP_Error('superfrete_document_required', __('CPF/CNPJ é um campo obrigatório.', 'superfrete'));
    168185        }
    169        
     186
    170187        if (!$this->is_valid_document($field_value)) {
    171188            return new \WP_Error('superfrete_document_invalid', __('CPF/CNPJ não é válido.', 'superfrete'));
    172189        }
    173        
     190
    174191        return true;
    175192    }
     
    205222    public function save_document_from_blocks($customer, $request)
    206223    {
    207         error_log('SuperFrete DocumentFields: Saving document from blocks');
    208        
     224        Logger::debug('Saving document from blocks', 'DocumentFields');
     225
    209226        $document = $request->get_param('billing_document');
    210227        if ($document) {
     
    218235    public function validate_document_in_blocks($request, $errors)
    219236    {
    220         error_log('SuperFrete DocumentFields: Validating document in blocks');
     237        Logger::debug('Validating document in blocks', 'DocumentFields');
    221238       
    222239        $document = $request->get_param('billing_document');
     
    233250    public function save_document_from_checkout_blocks($order_id, $posted_data, $order)
    234251    {
    235         error_log('SuperFrete DocumentFields: save_document_from_checkout_blocks called for order ' . $order_id);
    236         error_log('SuperFrete DocumentFields: Posted data keys: ' . implode(', ', array_keys($posted_data)));
    237        
     252        Logger::debug('save_document_from_checkout_blocks called for order ' . $order_id, 'DocumentFields');
     253        Logger::debug('Posted data keys: ' . implode(', ', array_keys($posted_data)), 'DocumentFields');
     254
    238255        // Try to find the document field in posted data
    239256        $document = '';
    240        
     257
    241258        // Check various possible field names for blocks checkout
    242259        $possible_keys = array(
    243260            'superfrete/document',
    244             'superfrete--document', 
     261            'superfrete--document',
    245262            'billing_document',
    246263            'extensions',
    247264        );
    248        
     265
    249266        foreach ($possible_keys as $key) {
    250267            if (isset($posted_data[$key])) {
     
    253270                    if (isset($posted_data[$key]['superfrete']) && isset($posted_data[$key]['superfrete']['document'])) {
    254271                        $document = sanitize_text_field($posted_data[$key]['superfrete']['document']);
    255                         error_log('SuperFrete DocumentFields: Found document in extensions: ' . $document);
     272                        Logger::debug('Found document in extensions: ' . $document, 'DocumentFields');
    256273                        break;
    257274                    }
    258275                } else {
    259276                    $document = sanitize_text_field($posted_data[$key]);
    260                     error_log('SuperFrete DocumentFields: Found document in ' . $key . ': ' . $document);
     277                    Logger::debug('Found document in ' . $key . ': ' . $document, 'DocumentFields');
    261278                    break;
    262279                }
    263280            }
    264281        }
    265        
     282
    266283        if (!empty($document)) {
    267284            $order->update_meta_data('_billing_document', $document);
    268285            $order->update_meta_data('_superfrete_document', $document);
    269286            $order->save();
    270             error_log('SuperFrete DocumentFields: Document saved from blocks checkout: ' . $document);
     287            Logger::debug('Document saved from blocks checkout: ' . $document, 'DocumentFields');
    271288        } else {
    272             error_log('SuperFrete DocumentFields: No document found in blocks checkout data');
     289            Logger::debug('No document found in blocks checkout data', 'DocumentFields');
    273290        }
    274291    }
     
    279296    public function save_document_from_store_api($order_data, $request)
    280297    {
    281         error_log('SuperFrete DocumentFields: save_document_from_store_api called');
    282         error_log('SuperFrete DocumentFields: Order data keys: ' . implode(', ', array_keys($order_data)));
    283        
     298        Logger::debug('save_document_from_store_api called', 'DocumentFields');
     299        Logger::debug('Order data keys: ' . implode(', ', array_keys($order_data)), 'DocumentFields');
     300
    284301        // Check if our field is in the request
    285302        $document_value = '';
    286        
     303
    287304        // Try to get the field value from various possible locations
    288305        if (method_exists($request, 'get_param')) {
     
    290307            if (is_array($extensions) && isset($extensions['superfrete']) && isset($extensions['superfrete']['document'])) {
    291308                $document_value = sanitize_text_field($extensions['superfrete']['document']);
    292                 error_log('SuperFrete DocumentFields: Found document in extensions: ' . $document_value);
    293             }
    294            
     309                Logger::debug('Found document in extensions: ' . $document_value, 'DocumentFields');
     310            }
     311
    295312            // Also try direct parameter
    296313            $direct_value = $request->get_param('superfrete/document');
    297314            if ($direct_value) {
    298315                $document_value = sanitize_text_field($direct_value);
    299                 error_log('SuperFrete DocumentFields: Found document in direct param: ' . $document_value);
    300             }
    301         }
    302        
     316                Logger::debug('Found document in direct param: ' . $document_value, 'DocumentFields');
     317            }
     318        }
     319
    303320        // If we found a document value, add it to the order data meta
    304321        if (!empty($document_value)) {
     
    306323                $order_data['meta_data'] = array();
    307324            }
    308            
     325
    309326            $order_data['meta_data'][] = array(
    310327                'key' => '_billing_document',
     
    312329            );
    313330            $order_data['meta_data'][] = array(
    314                 'key' => '_superfrete_document', 
     331                'key' => '_superfrete_document',
    315332                'value' => $document_value
    316333            );
    317            
    318             error_log('SuperFrete DocumentFields: Added document to order meta data: ' . $document_value);
     334
     335            Logger::debug('Added document to order meta data: ' . $document_value, 'DocumentFields');
    319336        } else {
    320             error_log('SuperFrete DocumentFields: No document found in Store API request');
    321         }
    322        
     337            Logger::debug('No document found in Store API request', 'DocumentFields');
     338        }
     339
    323340        return $order_data;
    324341    }
     
    329346    public function valid_checkout_fields()
    330347    {
    331         error_log('SuperFrete DocumentFields: valid_checkout_fields called');
    332        
    333         if (empty($_POST['billing_document'])) {
     348        Logger::debug('valid_checkout_fields called', 'DocumentFields');
     349
     350        $document = '';
     351
     352        // Try to get document from billing_document first (standard or merged from WooFunnels)
     353        if (!empty($_POST['billing_document'])) {
     354            $document = sanitize_text_field($_POST['billing_document']);
     355        }
     356
     357        // Fallback: Check WooFunnels CPF field
     358        if (empty($document) && !empty($_POST['billing_cpf'])) {
     359            $document = sanitize_text_field($_POST['billing_cpf']);
     360            Logger::debug('Using billing_cpf for validation: ' . $document, 'DocumentFields');
     361        }
     362
     363        // Fallback: Check WooFunnels CNPJ field
     364        if (empty($document) && !empty($_POST['billing_cnpj'])) {
     365            $document = sanitize_text_field($_POST['billing_cnpj']);
     366            Logger::debug('Using billing_cnpj for validation: ' . $document, 'DocumentFields');
     367        }
     368
     369        if (empty($document)) {
    334370            wc_add_notice(sprintf('<strong>%s</strong> %s.', __('CPF/CNPJ', 'superfrete'), __('é um campo obrigatório', 'superfrete')), 'error');
    335371            return;
    336372        }
    337373
    338         $document = sanitize_text_field($_POST['billing_document']);
    339        
    340374        if (!$this->is_valid_document($document)) {
    341375            wc_add_notice(sprintf('<strong>%s</strong> %s.', __('CPF/CNPJ', 'superfrete'), __('não é válido', 'superfrete')), 'error');
     
    348382    public function save_document_field($order_id)
    349383    {
    350         error_log('SuperFrete DocumentFields: save_document_field called for order ' . $order_id);
    351        
     384        Logger::debug('save_document_field called for order ' . $order_id, 'DocumentFields');
     385
    352386        // Handle both classic checkout and blocks checkout
    353387        $document = '';
    354        
     388
    355389        // Try to get from POST (classic checkout)
    356390        if (!empty($_POST['billing_document'])) {
    357391            $document = sanitize_text_field($_POST['billing_document']);
    358             error_log('SuperFrete DocumentFields: Document from POST: ' . $document);
    359         }
    360        
     392            Logger::debug('Document from POST billing_document: ' . $document, 'DocumentFields');
     393        }
     394
    361395        // Try to get from blocks checkout field
    362396        if (empty($document) && !empty($_POST['superfrete--document'])) {
    363397            $document = sanitize_text_field($_POST['superfrete--document']);
    364             error_log('SuperFrete DocumentFields: Document from blocks field: ' . $document);
    365         }
    366        
     398            Logger::debug('Document from blocks field: ' . $document, 'DocumentFields');
     399        }
     400
    367401        // Also try the namespaced field format
    368402        if (empty($document) && !empty($_POST['superfrete/document'])) {
    369403            $document = sanitize_text_field($_POST['superfrete/document']);
    370             error_log('SuperFrete DocumentFields: Document from namespaced field: ' . $document);
    371         }
    372        
     404            Logger::debug('Document from namespaced field: ' . $document, 'DocumentFields');
     405        }
     406
     407        // Try WooFunnels CPF field
     408        if (empty($document) && !empty($_POST['billing_cpf'])) {
     409            $document = sanitize_text_field($_POST['billing_cpf']);
     410            Logger::debug('Document from WooFunnels billing_cpf: ' . $document, 'DocumentFields');
     411        }
     412
     413        // Try WooFunnels CNPJ field
     414        if (empty($document) && !empty($_POST['billing_cnpj'])) {
     415            $document = sanitize_text_field($_POST['billing_cnpj']);
     416            Logger::debug('Document from WooFunnels billing_cnpj: ' . $document, 'DocumentFields');
     417        }
     418
    373419        if (!empty($document)) {
    374420            $order = wc_get_order($order_id);
     
    377423                $order->update_meta_data('_superfrete_document', $document);
    378424                $order->save();
    379                 error_log('SuperFrete DocumentFields: Document saved to order meta: ' . $document);
     425                Logger::debug('Document saved to order meta: ' . $document, 'DocumentFields');
    380426            }
    381427        } else {
    382             error_log('SuperFrete DocumentFields: No document found in POST data');
    383             error_log('SuperFrete DocumentFields: POST keys: ' . implode(', ', array_keys($_POST)));
     428            Logger::debug('No document found in POST data', 'DocumentFields');
     429            Logger::debug('POST keys: ' . implode(', ', array_keys($_POST)), 'DocumentFields');
    384430        }
    385431    }
  • superfrete/trunk/app/Controllers/OAuthController.php

    r3341621 r3427707  
    33namespace SuperFrete_API\Controllers;
    44
     5use SuperFrete_API\Helpers\Logger;
    56use WP_REST_Server;
    67use WP_REST_Request;
     
    2930    public function register_routes()
    3031    {
    31         // Add debug logging
    32         error_log('SuperFrete OAuth: Registering REST API routes');
    33        
    3432        // Proxy endpoint for polling OAuth token
    35         $result = register_rest_route('superfrete/v1', '/oauth/token', [
     33        register_rest_route('superfrete/v1', '/oauth/token', [
    3634            'methods' => WP_REST_Server::READABLE,
    3735            'callback' => [$this, 'proxy_oauth_token'],
     
    4543            ]
    4644        ]);
    47        
    48         if ($result) {
    49             error_log('SuperFrete OAuth: REST route registered successfully');
    50         } else {
    51             error_log('SuperFrete OAuth: Failed to register REST route');
    52         }
    5345    }
    5446   
     
    5850    public function ajax_oauth_proxy()
    5951    {
    60         error_log('SuperFrete OAuth: AJAX proxy called');
    61        
     52        Logger::debug('AJAX proxy called', 'OAuth');
     53
    6254        // Check nonce for security
    6355        if (!isset($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'wp_rest')) {
     
    6557            return;
    6658        }
    67        
     59
    6860        $session_id = sanitize_text_field($_GET['session_id'] ?? '');
    69         error_log('SuperFrete OAuth: AJAX session_id = ' . $session_id);
    70        
     61        Logger::debug('AJAX session_id = ' . $session_id, 'OAuth');
     62
    7163        if (empty($session_id)) {
    7264            wp_send_json_error('Session ID is required');
    7365            return;
    7466        }
    75        
     67
    7668        // Get the headless API URL from settings
    7769        $api_url = $this->get_headless_api_url();
     
    8072            return;
    8173        }
    82        
     74
    8375        // Make server-side request to headless API
    8476        $url = $api_url . '/headless/oauth/token?session_id=' . urlencode($session_id);
    85         error_log('SuperFrete OAuth: AJAX calling URL = ' . $url);
    86        
     77        Logger::debug('AJAX calling URL = ' . $url, 'OAuth');
     78
    8779        $response = wp_remote_get($url, [
    8880            'timeout' => 30,
     
    9284            ]
    9385        ]);
    94        
     86
    9587        if (is_wp_error($response)) {
    96             error_log('SuperFrete OAuth: AJAX wp_remote_get error = ' . $response->get_error_message());
     88            Logger::debug('AJAX wp_remote_get error = ' . $response->get_error_message(), 'OAuth');
    9789            wp_send_json_error('Failed to connect to headless API: ' . $response->get_error_message());
    9890            return;
    9991        }
    100        
     92
    10193        $status_code = wp_remote_retrieve_response_code($response);
    10294        $body = wp_remote_retrieve_body($response);
    103        
    104         error_log('SuperFrete OAuth: AJAX response status = ' . $status_code);
    105         error_log('SuperFrete OAuth: AJAX response body = ' . $body);
    106        
     95
     96        Logger::debug('AJAX response status = ' . $status_code, 'OAuth');
     97        Logger::debug('AJAX response body = ' . $body, 'OAuth');
     98
    10799        // Try to decode JSON response
    108100        $data = json_decode($body, true);
     
    111103            return;
    112104        }
    113        
     105
    114106        // Return the data
    115107        wp_send_json($data);
     
    124116    public function proxy_oauth_token(WP_REST_Request $request)
    125117    {
    126         error_log('SuperFrete OAuth: proxy_oauth_token called');
    127        
     118        Logger::debug('proxy_oauth_token called', 'OAuth');
     119
    128120        $session_id = $request->get_param('session_id');
    129         error_log('SuperFrete OAuth: session_id = ' . $session_id);
    130        
     121        Logger::debug('session_id = ' . $session_id, 'OAuth');
     122
    131123        if (empty($session_id)) {
    132             error_log('SuperFrete OAuth: Missing session_id');
     124            Logger::debug('Missing session_id', 'OAuth');
    133125            return new WP_Error('missing_session_id', 'Session ID is required', ['status' => 400]);
    134126        }
     
    177169        // Check if we're in sandbox mode
    178170        $sandbox_mode = get_option('superfrete_sandbox_mode', 'no');
    179        
    180         // Debug logging
    181         error_log('SuperFrete OAuth: sandbox_mode setting = ' . $sandbox_mode);
    182        
     171
     172        Logger::debug('sandbox_mode setting = ' . $sandbox_mode, 'OAuth');
     173
    183174        if ($sandbox_mode === 'yes') {
    184175            // Development/sandbox environment
    185176            $api_url = 'https://api.dev.superintegrador.superfrete.com';
    186             error_log('SuperFrete OAuth: Using dev API = ' . $api_url);
     177            Logger::debug('Using dev API = ' . $api_url, 'OAuth');
    187178            return $api_url;
    188179        } else {
    189180            // Production environment
    190181            $api_url = 'https://api.superintegrador.superfrete.com';
    191             error_log('SuperFrete OAuth: Using production API = ' . $api_url);
     182            Logger::debug('Using production API = ' . $api_url, 'OAuth');
    192183            return $api_url;
    193184        }
  • superfrete/trunk/app/Controllers/ProductShipping.php

    r3341706 r3427707  
    33namespace SuperFrete_API\Controllers;
    44
     5use SuperFrete_API\Helpers\Logger;
    56use SuperFrete_API\Http\Request;
    67use WC_Shipping_Zones;
     
    171172                        ],
    172173                        'cart_subtotal' => $product->get_price() * $quantity,
     174                        // Add custom field to indicate this is a product page calculation with specific quantity
     175                        'superfrete_product_calc' => true,
     176                        'superfrete_requested_quantity' => $quantity,
    173177                    ];
    174178                   
     
    392396            // Add log data to the return for debugging
    393397            $return['performance_log'] = $log_data;
    394            
    395             // Log to the WordPress error log
    396             error_log('SuperFrete Performance Log: ' . wp_json_encode($log_data));
     398
     399            // Log performance data
     400            Logger::debug('Performance Log: ' . wp_json_encode($log_data), 'ProductShipping');
    397401           
    398402            echo wp_json_encode($return);
     
    448452
    449453    static function addProductToCart($product_id, $variation_id, $quantity = 1) {
    450         $consider_product_quantity = apply_filters('superfrete_ppscw_consider_quantity_in_shipping_calculation', get_option('superfrete_consider_quantity_field', 'dont-consider-quantity-field'), $product_id, $variation_id, $quantity);
    451 
    452         if ($consider_product_quantity == 'dont-consider-quantity-field') {
    453             if (self::productExistInCart($product_id, $variation_id))
    454                 return "";
    455             $quantity = 1;
    456         }
    457 
     454        // Always use the actual quantity - removed the broken quantity override logic
     455       
    458456        if (!empty($variation_id)) {
    459457            $variation = self::getVariationAttributes($variation_id);
  • superfrete/trunk/readme.txt

    r3344807 r3427707  
    55Tested up to: 6.7
    66Requires PHP: 7.4
    7 Stable tag: 3.3.2
     7Stable tag: 3.3.3
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    7272== Changelog ==
    7373
     74= 3.3.3 =
     75* **Logs Otimizados:** Substituído error_log() por sistema de Logger condicional
     76* **Modo Debug Configurável:** Nova opção em Configurações Avançadas para controlar logs de debug
     77* **Respeita WP_DEBUG:** Logs de debug só são gerados quando WP_DEBUG está ativo ou modo debug habilitado
     78* **Performance em Produção:** Removidos logs de inicialização que poluíam o error_log a cada requisição
     79* **Logs de Eventos Preservados:** Mantidos logs úteis para checkout, validação e erros de API
     80
    7481= 3.3.1 =
    7582
  • superfrete/trunk/superfrete.php

    r3341728 r3427707  
    33  Plugin Name: SuperFrete
    44  Description: Plugin that provides integration with the SuperFrete platform.
    5   Version:     3.3.1
     5  Version:     3.3.3
    66  Author:      Super Frete
    77  Author URI:  https://superfrete.com/
Note: See TracChangeset for help on using the changeset viewer.