/** CSS del sello vendido con colores, opacidades, textura y textos editables. */ public static function get_sold_badge_css() { $text_rgba = self::hex_to_rgba( self::get_color( 'design_sold_text_color', '#ffffff' ), self::get( 'design_sold_text_opacity', 82 ) ); $background = self::get_sold_background_css(); $moto_label = wp_json_encode( self::get_text( 'text_sold_badge_motorcycle', 'VENDIDA' ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); $auto_label = wp_json_encode( self::get_text( 'text_sold_badge_automobile', 'VENDIDO' ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); return '.luxus-gallery-sold-badge,.luxus-vehicle-is-sold .box-image::after{color:' . $text_rgba . ';background:' . $background . '}.luxus-motorcycle-is-sold .box-image::after{content:' . $moto_label . '}.luxus-automobile-is-sold .box-image::after{content:' . $auto_label . '}'; } /** Devuelve el número de WhatsApp normalizado, con respaldo seguro. */ public static function get_whatsapp_number() { $number = preg_replace( '/\D+/', '', (string) self::get( 'whatsapp_number', '56957448826' ) ); return strlen( $number ) >= 8 && strlen( $number ) <= 15 ? $number : '56957448826'; } /** Devuelve una URL administrativa válida o el respaldo calculado. */ public static function get_url( $key, $fallback ) { $url = esc_url_raw( (string) self::get( $key, '' ) ); return $url ? $url : esc_url_raw( (string) $fallback ); } /** Porcentaje global de pie usado en las fichas Luxus. */ public static function get_finance_down_payment_percent() { return max( 0, min( 90, absint( self::get( 'finance_down_payment_percent', 30 ) ) ) ); } /** Cantidad máxima de cuotas mostrada en las fichas Luxus. */ public static function get_finance_max_installments() { return max( 1, min( 84, absint( self::get( 'finance_max_installments', 48 ) ) ) ); } /** Renta mínima referencial mostrada en las fichas Luxus. */ public static function get_finance_minimum_income() { return max( 0, absint( self::get( 'finance_minimum_income', 600000 ) ) ); } /** Sanitiza posiciones 1-indexadas de galería, máximo tres. */ public static function get_similar_image_positions() { $raw = preg_split( '/[^0-9]+/', (string) self::get( 'similar_image_positions', '2,4,7' ) ); $out = array(); foreach ( $raw as $position ) { $position = absint( $position ); if ( $position > 0 && $position <= 50 && ! in_array( $position, $out, true ) ) { $out[] = $position; } } return array_slice( $out ?: array( 2, 4, 7 ), 0, 3 ); } /** Devuelve el intervalo seguro de la secuencia. */ public static function get_similar_interval() { return max( 3000, min( 8000, absint( self::get( 'similar_interval_ms', 4000 ) ) ) ); } /** Devuelve una asociación de icono personalizada. */ public static function get_icon_attachment_id( $key ) { static $overrides = null; if ( null === $overrides ) { $value = get_option( self::OPTION_ICONS, array() ); $overrides = is_array( $value ) ? $value : array(); } $key = sanitize_key( $key ); return isset( $overrides[ $key ] ) ? absint( $overrides[ $key ] ) : 0; } /** Busca un logo administrado por el plugin antes de usar el de otro catálogo. */ public static function get_brand_logo_id( $term_id ) { return absint( get_term_meta( absint( $term_id ), self::TERM_LOGO_META, true ) ); } /** * Logos iniciales incluidos con el plugin. Un archivo subido desde el panel * siempre tiene prioridad y permite reemplazarlos sin editar código. */ public static function get_bundled_brand_logos() { return array( 'bmw' => 'bmw.png', 'triumph' => 'triumph.png', 'ducati' => 'ducati.png', 'honda' => 'honda.png', 'ktm' => 'ktm.png', 'benelli' => 'benelli.png', 'cfmoto' => 'cfmoto.png', 'husqvarna' => 'husqvarna.png', 'kawasaki' => 'kawasaki.png', 'royal-enfield' => 'royal-enfield.png', 'suzuki' => 'suzuki.png', 'yamaha' => 'yamaha.svg', 'volkswagen' => 'volkswagen.svg', 'mercedes-benz' => 'mercedes-benz.svg', 'audi' => 'audi.svg', 'toyota' => 'toyota.svg', 'ford' => 'ford.png', 'chevrolet' => 'chevrolet.png', 'nissan' => 'nissan.svg', 'subaru' => 'subaru.png', 'mazda' => 'mazda.svg', 'hyundai' => 'hyundai.svg', 'kia' => 'kia.svg', ); } /** Normaliza variaciones habituales del nombre comercial. */ public static function normalize_brand_key( $name ) { $key = sanitize_title( remove_accents( (string) $name ) ); $aliases = array( 'cf-moto' => 'cfmoto', 'cf-motos' => 'cfmoto', 'royalenfield' => 'royal-enfield', 'mercedes' => 'mercedes-benz', 'mercedes-benz' => 'mercedes-benz', 'mercedesbenz' => 'mercedes-benz', 'yamaha-motor' => 'yamaha', 'yamaha-motors' => 'yamaha', ); return isset( $aliases[ $key ] ) ? $aliases[ $key ] : $key; } /** Devuelve el logo incluido que coincide con una marca o una cadena vacía. */ public static function get_bundled_brand_logo_url( $name ) { $logos = self::get_bundled_brand_logos(); $key = self::normalize_brand_key( $name ); if ( ! isset( $logos[ $key ] ) ) { return '';