<?php if ( ! defined( 'ABSPATH' ) ) exit; class GT_BOGO_Scarcity_Bar { private $id = 'scarcity_bar'; public function __construct() { if ( is_admin() && ! defined('DOING_AJAX') ) return; if ( ! $this->enabled() ) return; add_action( 'wp_enqueue_scripts', [ $this, 'enqueue' ] ); } private function enabled() { return (bool) get_option( 'gtbogo_sp_' . $this->id . '_enabled', 0 ) && get_option( 'gtbogo_sp_' . $this->id . '_intensity', 'subtle' ) !== 'off'; } private function intensity() { return get_option( 'gtbogo_sp_' . $this->id . '_intensity', 'subtle' ); } private function styles() { $map = [ 'subtle' => [ 'font_size' => '0.78em', 'padding' => '8px 12px', 'opacity' => '0.70' ], 'moderate' => [ 'font_size' => '0.85em', 'padding' => '10px 14px', 'opacity' => '0.85' ], 'bold' => [ 'font_size' => '0.9em', 'padding' => '12px 16px', 'opacity' => '1.0' ], ]; return $map[ $this->intensity() ] ?? $map['subtle']; } private function threshold() { return (int) get_option( 'gtbogo_sp_' . $this->id . '_threshold', 10 ); } public function enqueue() { wp_add_inline_style( 'woocommerce-general', ' .gtbogo-scarcity{display:flex;align-items:center;gap:10px;font-family:inherit;color:inherit;margin:12px 0;box-sizing:border-box} .gtbogo-scarcity-track{flex:1;height:4px;background:currentColor;opacity:0.15;border-radius:2px;overflow:hidden} .gtbogo-scarcity-fill{height:100%;background:currentColor;border-radius:2px;transition:width 0.6s ease} .gtbogo-scarcity-text{font-family:inherit;white-space:nowrap;font-weight:600} .gtbogo-scarcity-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0;animation:gtbogo-pulse 1.8s infinite} @keyframes gtbogo-pulse{0%,100%{opacity:1}50%{opacity:0.3}} ' ); } private function get_stock_data( $product_id = 0 ) { if ( $product_id ) { $product = wc_get_product( $product_id ); } else { global $product; } if ( ! $product || ! $product->managing_stock() ) return null; $stock = $product->get_stock_quantity(); if ( $stock === null || $stock > $this->threshold() ) return null; $max = max( $this->threshold(), $stock ); $pct = $max > 0 ? round( ( $stock / $max ) * 100 ) : 0; return [ 'stock' => $stock, 'pct' => $pct ]; } public function render() { $data = $this->get_stock_data(); if ( ! $data ) return; $s = $this->styles(); $stock = $data['stock']; $pct = $data['pct']; $text = $stock <= 3 ? sprintf( esc_html__( 'Only %d left — deal ends when stock runs out', 'gt-bogo-engine' ), $stock ) : sprintf( esc_html__( '%d remaining at this price', 'gt-bogo-engine' ), $stock ); ?> <div class="gtbogo-scarcity" style="padding:<?php echo esc_attr($s['padding']); ?>;font-size:<?php echo esc_attr($s['font_size']); ?>;opacity:<?php echo esc_attr($s['opacity']); ?>"> <span class="gtbogo-scarcity-dot"></span> <div class="gtbogo-scarcity-track"> <div class="gtbogo-scarcity-fill" style="width:<?php echo esc_attr($pct); ?>%"></div> </div> <span class="gtbogo-scarcity-text"><?php echo esc_html( $text ); ?></span> </div> <?php } public function render_loop() { global $product; if ( ! $product ) return; $data = $this->get_stock_data( $product->get_id() ); if ( ! $data ) return; $s = $this->styles(); ?> <div class="gtbogo-scarcity" style="padding:<?php echo esc_attr($s['padding']); ?>;font-size:<?php echo esc_attr($s['font_size']); ?>;opacity:<?php echo esc_attr($s['opacity']); ?>"> <span class="gtbogo-scarcity-dot"></span> <span class="gtbogo-scarcity-text"><?php echo esc_html( sprintf( __( 'Only %d left', 'gt-bogo-engine' ), $data['stock'] ) ); ?></span> </div> <?php } }