1, ); $settings = get_option( AHA_HERO_SLIDER_OPTION, array() ); if ( ! is_array( $settings ) ) { $settings = array(); } $settings = wp_parse_args( $settings, $defaults ); return ! empty( $settings['enable_slideshow'] ); } /** * Whether slider HTML should render on the current request. * * @return bool */ function aha_hero_slider_should_render_slider_output() { return aha_hero_slider_is_globally_enabled(); } /** * Normalizes shortcode / config transition keyword to slide | fade | vertical. * * @param string $raw User or default value (e.g. slide, fade, vertical-slide). * @return string One of slide, fade, vertical. */ function aha_hero_slider_sanitize_transition_mode( $raw ) { $t = strtolower( str_replace( '_', '-', trim( (string) $raw ) ) ); $map = array( 'slide' => 'slide', 'horizontal' => 'slide', 'fade' => 'fade', 'crossfade' => 'fade', 'cross-fade' => 'fade', 'vertical' => 'vertical', 'vertical-slide' => 'vertical', 'vertical-slider' => 'vertical', ); if ( isset( $map[ $t ] ) ) { return $map[ $t ]; } return 'slide'; } /** * Autoplay progress indicator mode from shortcode / config. * * @param string $raw e.g. bar, circle, off, empty. * @return string '' (off), bar, or circle. */ function aha_hero_slider_sanitize_progress_mode( $raw ) { $t = strtolower( str_replace( '_', '-', trim( (string) $raw ) ) ); if ( $t === '' || $t === '0' || $t === 'no' || $t === 'off' || $t === 'false' || $t === 'none' ) { return ''; } if ( $t === 'bar' ) { return 'bar'; } if ( $t === 'circle' || $t === 'ring' ) { return 'circle'; } return ''; } /** * Heading tag for slide headline (shortcode title_tag). * * @param string $raw e.g. h1, H3, heading4. * @return string One of h1–h6; invalid values become h2. */ function aha_hero_slider_sanitize_title_heading_tag( $raw ) { $t = strtolower( trim( (string) $raw ) ); if ( preg_match( '/^h[1-6]$/', $t ) ) { return $t; } return 'h2'; } /** * Sanitize a hex color; empty string if invalid (use theme/CSS default). * * @param string $raw User or option input. * @return string '' or #rrggbb. */ function aha_hero_slider_sanitize_hex_color_or_empty( $raw ) { $c = sanitize_hex_color( trim( (string) $raw ) ); return $c ? $c : ''; } /** * Sanitize CSS background-size for slide images. * * Kept intentionally strict (whitelist) since the value is printed into inline CSS vars. * * @since 1.0.0 * * @param string $raw User/meta value. * @return string '' if invalid/empty, otherwise a safe CSS keyword/value. */ function aha_hero_slider_sanitize_bg_size( $raw ) { $v = strtolower( trim( (string) $raw ) ); $v = str_replace( array( '_', "\t", "\n", "\r" ), ' ', $v ); $v = preg_replace( '/\s+/', ' ', $v ); if ( $v === '' ) { return ''; } $allowed = array( 'cover' => true, 'contain' => true, 'auto' => true, '100% 100%' => true, '100% auto' => true, 'auto 100%' => true, ); return isset( $allowed[ $v ] ) ? $v : ''; } /** * Sanitize CSS background-position for slide images. * * @since 1.0.0 * * @param string $raw User/meta value. * @return string '' if invalid/empty, otherwise a safe CSS keyword combination. */ function aha_hero_slider_sanitize_bg_position( $raw ) { $v = strtolower( trim( (string) $raw ) ); $v = str_replace( array( '_', "\t", "\n", "\r" ), ' ', $v ); $v = preg_replace( '/\s+/', ' ', $v ); if ( $v === '' ) { return ''; } $allowed = array( 'center' => true, 'center left' => true, 'center right' => true, 'top' => true, 'top left' => true, 'top right' => true, 'bottom' => true, 'bottom left' => true, 'bottom right' => true, 'left' => true, 'right' => true, ); return isset( $allowed[ $v ] ) ? $v : ''; } /** * Keeps only allowed custom-property names and valid hex values (shortcode instance overrides). * * @param array $raw Map --aha-hs-* => color or rgba(). * @return array */ function aha_hero_slider_sanitize_instance_css_vars( array $raw ) { $allowed = array( '--aha-hs-progress-track' => true, '--aha-hs-progress-fill' => true, '--aha-hs-arrow-bg' => true, '--aha-hs-arrow-icon' => true, '--aha-hs-bullet' => true, '--aha-hs-bullet-active' => true, '--aha-hs-overlay' => true, ); $out = array(); foreach ( $raw as $var_name => $val ) { if ( ! is_string( $var_name ) || ! isset( $allowed[ $var_name ] ) ) { continue; } // Overlay is already rgba() formatted, pass through if ( '--aha-hs-overlay' === $var_name ) { if ( '' !== trim( (string) $val ) ) { $out[ $var_name ] = $val; } continue; } $hex = aha_hero_slider_sanitize_hex_color_or_empty( (string) $val ); if ( $hex !== '' ) { $out[ $var_name ] = $hex; } } return $out; } /** * Maps shortcode color attributes to custom-property keys (values sanitized in sanitize_instance_css_vars). * * @param array $atts Shortcode attributes. * @return array */ function aha_hero_slider_instance_css_vars_from_shortcode_atts( array $atts ) { $map = array( 'progress_track' => '--aha-hs-progress-track', 'progress_fill' => '--aha-hs-progress-fill', 'arrow_bg' => '--aha-hs-arrow-bg', 'arrow_icon' => '--aha-hs-arrow-icon', 'bullet' => '--aha-hs-bullet', 'bullet_active' => '--aha-hs-bullet-active', ); $raw = array(); foreach ( $map as $att => $var ) { if ( ! isset( $atts[ $att ] ) ) { continue; } $v = trim( (string) $atts[ $att ] ); if ( $v === '' ) { continue; } $raw[ $var ] = $v; } // Process overlay separately (enabled, color, opacity) if ( isset( $atts['overlay'] ) ) { $overlay_mode = strtolower( trim( (string) $atts['overlay'] ) ); // overlay="off" or overlay="no" or overlay="0" disables overlay if ( in_array( $overlay_mode, array( 'off', 'no', '0', 'false' ), true ) ) { $raw['--aha-hs-overlay'] = 'transparent'; } elseif ( in_array( $overlay_mode, array( 'on', 'yes', '1', 'true' ), true ) || '' !== $overlay_mode ) { // overlay="on" or overlay="yes" uses color and opacity from attributes or defaults $color = isset( $atts['overlay_color'] ) ? trim( (string) $atts['overlay_color'] ) : '#000000'; $opacity = isset( $atts['overlay_opacity'] ) ? absint( $atts['overlay_opacity'] ) : 40; $hex = sanitize_hex_color( $color ); if ( $hex ) { $hex = ltrim( $hex, '#' ); if ( strlen( $hex ) === 3 ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $r = hexdec( substr( $hex, 0, 2 ) ); $g = hexdec( substr( $hex, 2, 2 ) ); $b = hexdec( substr( $hex, 4, 2 ) ); $a = round( max( 0, min( 100, $opacity ) ) / 100, 2 ); $raw['--aha-hs-overlay'] = 'rgba(' . $r . ',' . $g . ',' . $b . ',' . $a . ')'; } } } return aha_hero_slider_sanitize_instance_css_vars( $raw ); } /** * Resolves the headline wrapper tag for one slide (SEO: at most one h1 per slider). * * When `title_tag` is h1, only slide index 0 uses h1; later slides use h2. Other levels (h2–h6) apply to every slide. * * @param string $title_tag Already-sanitized h1–h6. * @param int $slide_index Zero-based slide order in the slider. * @return string h1–h6. */ function aha_hero_slider_headline_tag_for_slide( $title_tag, $slide_index ) { $tag = aha_hero_slider_sanitize_title_heading_tag( (string) $title_tag ); if ( $tag === 'h1' && (int) $slide_index > 0 ) { return 'h2'; } return $tag; } /** * Attachment URL from ID (always full size). * * @param int $attachment_id Attachment ID. * @return string */ function aha_hero_slider_get_image_url( $attachment_id ) { $attachment_id = absint( $attachment_id ); if ( ! $attachment_id ) { return ''; } $url = wp_get_attachment_image_url( $attachment_id, 'full' ); return $url ? $url : ''; } /** * Register custom image sizes for hero slides when the setting is enabled. * * Desktop: 1870 × 520 px (hard crop) — covers full-width sliders on large screens. * Mobile : 640 × 400 px (hard crop) — card layouts with a 200px strip (default / video + text). * Mobile (full-bleed video poster): 960 px wide, proportional height (soft) — tall cards with * `background-size: cover` (Pro “Video — full image”); avoids a portrait crop from 640×400. * * @return void */ function aha_hero_slider_register_image_sizes() { $settings = get_option( AHA_HERO_SLIDER_OPTION, array() ); if ( ! isset( $settings['enable_custom_image_sizes'] ) || ! empty( $settings['enable_custom_image_sizes'] ) ) { add_image_size( 'aha-hero-desktop', 1870, 520, true ); add_image_size( 'aha-hero-mobile', 640, 400, true ); add_image_size( 'aha-hero-mobile-full', 960, 0, false ); } } /** * Returns the slide image URL using the appropriate registered size when available, * falling back to the full-size URL. * * @param int $attachment_id Attachment ID. * @param string $context 'desktop' or 'mobile'. * @param string $slide_layout Optional layout slug (e.g. `video_full` uses a taller soft-resize for mobile). * @return string */ function aha_hero_slider_get_slide_image_url( $attachment_id, $context = 'desktop', $slide_layout = '' ) { $attachment_id = absint( $attachment_id ); if ( ! $attachment_id ) { return ''; } $settings = get_option( AHA_HERO_SLIDER_OPTION, array() ); if ( ! isset( $settings['enable_custom_image_sizes'] ) || ! empty( $settings['enable_custom_image_sizes'] ) ) { $layout = is_string( $slide_layout ) ? $slide_layout : ''; if ( 'mobile' === $context && 'video_full' === $layout ) { $url = wp_get_attachment_image_url( $attachment_id, 'aha-hero-mobile-full' ); if ( ! $url ) { $url = wp_get_attachment_image_url( $attachment_id, 'aha-hero-mobile' ); } if ( $url ) { return $url; } } elseif ( 'mobile' === $context ) { $url = wp_get_attachment_image_url( $attachment_id, 'aha-hero-mobile' ); if ( $url ) { return $url; } } else { $url = wp_get_attachment_image_url( $attachment_id, 'aha-hero-desktop' ); if ( $url ) { return $url; } } } return aha_hero_slider_get_image_url( $attachment_id ); } /** * Default slide background URL when no desktop image is set (bundled SVG; override via filter). * * @return string */ function aha_hero_slider_get_default_slide_image_url() { $path = AHA_HERO_SLIDER_PATH . 'assets/images/slide-placeholder.svg'; $url = AHA_HERO_SLIDER_URL . 'assets/images/slide-placeholder.svg'; if ( ! is_readable( $path ) ) { $url = ''; } /** * Filter default hero slide image URL when the slide has no desktop attachment. * * @since 1.0.0 * * @param string $url Default image URL (empty if bundled file is missing). */ return (string) apply_filters( 'aha_hero_slider_default_slide_image_url', $url ); } /** * Build slide array from a CPT post. * * @param WP_Post $post Post object. * @return array */ function aha_hero_slider_slide_from_post( WP_Post $post ) { $desktop_id = (int) get_post_meta( $post->ID, '_aha_hero_image_desktop_id', true ); $mobile_id = (int) get_post_meta( $post->ID, '_aha_hero_image_mobile_id', true ); $link_url = (string) get_post_meta( $post->ID, '_aha_hero_link_url', true ); $layout_meta = (string) get_post_meta( $post->ID, '_aha_hero_slide_layout', true ); $slide_layout = aha_hero_slider_normalize_layout( $layout_meta ); $desktop_url = aha_hero_slider_get_slide_image_url( $desktop_id, 'desktop' ); if ( '' === $desktop_url ) { $desktop_url = aha_hero_slider_get_default_slide_image_url(); } return array( 'post_id' => $post->ID, 'slide_layout' => $slide_layout, 'kicker' => (string) get_post_meta( $post->ID, '_aha_hero_kicker', true ), 'headline' => (string) get_post_meta( $post->ID, '_aha_hero_headline', true ), 'subtitle' => (string) get_post_meta( $post->ID, '_aha_hero_subtitle', true ), 'button_text' => (string) get_post_meta( $post->ID, '_aha_hero_button_text', true ), 'button2_text' => (string) get_post_meta( $post->ID, '_aha_hero_button2_text', true ), 'link' => array( 'url' => $link_url, 'is_external' => get_post_meta( $post->ID, '_aha_hero_link_new_tab', true ) === '1' ? 'on' : '', ), 'link2' => array( 'url' => (string) get_post_meta( $post->ID, '_aha_hero_link2_url', true ), 'is_external' => get_post_meta( $post->ID, '_aha_hero_link2_new_tab', true ) === '1' ? 'on' : '', ), 'image_desktop' => array( 'url' => $desktop_url ), 'image_mobile' => array( 'url' => $mobile_id ? aha_hero_slider_get_slide_image_url( $mobile_id, 'mobile', $slide_layout ) : '' ), 'link_whole_banner' => get_post_meta( $post->ID, '_aha_hero_link_whole_banner', true ) === 'yes' ? 'yes' : '', 'hide_on_mobile' => array( 'badge' => get_post_meta( $post->ID, '_aha_hero_hide_badge_mobile', true ) === '1', 'headline' => get_post_meta( $post->ID, '_aha_hero_hide_headline_mobile', true ) === '1', 'subtitle' => get_post_meta( $post->ID, '_aha_hero_hide_subtitle_mobile', true ) === '1', 'primary' => get_post_meta( $post->ID, '_aha_hero_hide_btn1_mobile', true ) === '1', 'secondary' => get_post_meta( $post->ID, '_aha_hero_hide_btn2_mobile', true ) === '1', ), 'style' => array( 'badge_color' => (string) get_post_meta( $post->ID, '_aha_hero_badge_color', true ), 'badge_size' => (string) get_post_meta( $post->ID, '_aha_hero_badge_size', true ), 'headline_color' => (string) get_post_meta( $post->ID, '_aha_hero_headline_color', true ), 'headline_size' => (string) get_post_meta( $post->ID, '_aha_hero_headline_size', true ), 'subtitle_color' => (string) get_post_meta( $post->ID, '_aha_hero_subtitle_color', true ), 'subtitle_size' => (string) get_post_meta( $post->ID, '_aha_hero_subtitle_size', true ), 'btn1_bg' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_bg', true ), 'btn1_color' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_color', true ), 'btn1_border' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_border_color', true ), 'btn1_radius' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_radius', true ), 'btn2_bg' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_bg', true ), 'btn2_color' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_color', true ), 'btn2_border' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_border_color', true ), 'btn2_radius' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_radius', true ), 'mobile_card_bg' => (string) get_post_meta( $post->ID, '_aha_hero_mobile_card_bg', true ), 'btn1_bg_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_bg_mobile', true ), 'btn1_color_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_color_mobile', true ), 'btn1_border_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_border_color_mobile', true ), 'btn1_radius_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn1_radius_mobile', true ), 'btn2_bg_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_bg_mobile', true ), 'btn2_color_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_color_mobile', true ), 'btn2_border_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_border_color_mobile', true ), 'btn2_radius_mobile' => (string) get_post_meta( $post->ID, '_aha_hero_btn2_radius_mobile', true ), 'bg_size' => aha_hero_slider_sanitize_bg_size( (string) get_post_meta( $post->ID, '_aha_hero_bg_size', true ) ), 'bg_position' => aha_hero_slider_sanitize_bg_position( (string) get_post_meta( $post->ID, '_aha_hero_bg_position', true ) ), 'mobile_bg_size' => aha_hero_slider_sanitize_bg_size( (string) get_post_meta( $post->ID, '_aha_hero_mobile_bg_size', true ) ), 'mobile_bg_position' => aha_hero_slider_sanitize_bg_position( (string) get_post_meta( $post->ID, '_aha_hero_mobile_bg_position', true ) ), ), 'custom_css_id' => (string) get_post_meta( $post->ID, '_aha_hero_custom_css_id', true ), 'custom_css_classes' => (string) get_post_meta( $post->ID, '_aha_hero_custom_css_classes', true ), ); } /** * Allowed inline HTML for slide badge, headline, and subtitle (block tags would break outer <p> / heading wrapper). * * @return array> */ function aha_hero_slider_kses_slide_inline() { return array( 'br' => array(), 'strong' => array(), 'b' => array(), 'em' => array(), 'i' => array(), 'span' => array( 'class' => array(), 'style' => array(), ), 'small' => array(), 'sub' => array(), 'sup' => array(), 'mark' => array(), ); } /** * Sanitize slide rich text (inline HTML only). * * @param string $content Raw content. * @return string */ function aha_hero_slider_sanitize_slide_rich_text( $content ) { return wp_kses( (string) $content, aha_hero_slider_kses_slide_inline() ); } /** * Sanitize button / banner link URL: full URLs, same-site root-relative paths, or fragment-only (#anchor). * * @param string $url Raw URL. * @return string */ function aha_hero_slider_sanitize_button_url( $url ) { $url = trim( (string) wp_unslash( $url ) ); if ( '' === $url ) { return ''; } if ( preg_match( '/\Ajavascript:/i', $url ) || preg_match( '/\Adata:/i', $url ) || preg_match( '/\Avbscript:/i', $url ) ) { return ''; } // Same-page anchor, e.g. #cta. if ( preg_match( '/\A#[^\s#<>"\']*\z/u', $url ) ) { return $url; } // Root-relative path on this site (stored as absolute URL). if ( strlen( $url ) >= 1 && '/' === $url[0] && ( strlen( $url ) === 1 || '/' !== $url[1] ) ) { return esc_url_raw( home_url( $url ) ); } return esc_url_raw( $url ); } /** * Whether a slide link URL is fragment-only (e.g. #section) and should use esc_attr() in href. * * Full URLs use esc_url() at output time. Use this helper so templates can satisfy PHPCS * with explicit esc_attr()/esc_url() while sharing one rule with sanitize_button_url(). * * @param string $url Raw URL from slide data (already sanitized on save). * @return bool */ function aha_hero_slider_is_fragment_href( $url ) { $url = (string) $url; return ( '' !== $url && '#' === $url[0] ); } /** * Query slides from CPT. * * @param array $args Optional WP_Query args overrides. * @return WP_Post[] */ function aha_hero_slider_get_cpt_slides( $args = array() ) { if ( ! post_type_exists( AHA_HERO_SLIDER_CPT ) ) { return array(); } $group = null; if ( array_key_exists( 'group', $args ) ) { $group = $args['group']; unset( $args['group'] ); } $defaults = array( 'post_type' => AHA_HERO_SLIDER_CPT, 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC', 'no_found_rows' => true, ); $query_args = wp_parse_args( $args, $defaults ); if ( null !== $group && taxonomy_exists( AHA_HERO_SLIDER_TAXONOMY ) ) { $slugs = array(); if ( is_array( $group ) ) { $slugs = array_filter( array_map( 'sanitize_title', $group ) ); } else { $g = trim( (string) $group ); if ( $g !== '' ) { $slugs = array_filter( array_map( 'sanitize_title', array_map( 'trim', explode( ',', $g ) ) ) ); } } if ( ! empty( $slugs ) ) { $query_args['tax_query'] = array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query array( 'taxonomy' => AHA_HERO_SLIDER_TAXONOMY, 'field' => 'slug', 'terms' => array_values( array_unique( $slugs ) ), 'operator' => 'IN', ), ); } } /** * Filter CPT query args for hero slides. * * @since 1.0.0 * * @param array $query_args Query arguments. */ $query_args = apply_filters( 'aha_hero_slider_query_args', $query_args ); $q = new WP_Query( $query_args ); return $q->posts; } /** * Build the CSS custom-properties block from global design settings. * * @return string CSS string, scoped to .aha-hero-slider, or empty string. */ function aha_hero_slider_get_global_styles_css() { $settings = AHA_Hero_Slider_Settings::get_instance()->get_settings(); $vars = array(); $hex_map = array( 'color_arrow' => '--aha-hs-arrow-bg', 'color_arrow_icon' => '--aha-hs-arrow-icon', 'color_bullet' => '--aha-hs-bullet', 'color_bullet_active' => '--aha-hs-bullet-active', 'color_progress_track' => '--aha-hs-progress-track', 'color_progress_fill' => '--aha-hs-progress-fill', 'color_badge' => '--aha-hs-badge', 'color_headline' => '--aha-hs-headline', 'color_subtitle' => '--aha-hs-subtitle', 'color_btn1_bg' => '--aha-hs-btn1-bg', 'color_btn1_text' => '--aha-hs-btn1-color', 'color_btn1_border' => '--aha-hs-btn1-border', 'color_btn2_text' => '--aha-hs-btn2-color', 'color_btn2_border' => '--aha-hs-btn2-border', 'color_mobile_bg' => '--aha-hs-mobile-bg', ); foreach ( $hex_map as $key => $var ) { if ( ! empty( $settings[ $key ] ) ) { $safe_color = sanitize_hex_color( $settings[ $key ] ); if ( $safe_color ) { $vars[] = $var . ':' . $safe_color; } } } $btn2_bg = 'transparent'; if ( ! empty( $settings['color_btn2_bg'] ) ) { $safe_btn2 = sanitize_hex_color( $settings['color_btn2_bg'] ); if ( $safe_btn2 ) { $btn2_bg = $safe_btn2; } } $vars[] = '--aha-hs-btn2-bg:' . $btn2_bg; if ( isset( $settings['color_btn1_radius'] ) && '' !== (string) $settings['color_btn1_radius'] ) { $vars[] = '--aha-hs-btn1-radius:' . absint( $settings['color_btn1_radius'] ) . 'px'; } if ( isset( $settings['color_btn2_radius'] ) && '' !== (string) $settings['color_btn2_radius'] ) { $vars[] = '--aha-hs-btn2-radius:' . absint( $settings['color_btn2_radius'] ) . 'px'; } if ( ! empty( $settings['overlay_enabled'] ) && ! empty( $settings['overlay_color'] ) ) { $safe_overlay = sanitize_hex_color( $settings['overlay_color'] ); if ( ! $safe_overlay ) { $safe_overlay = '#000000'; } $opacity = isset( $settings['overlay_opacity'] ) ? max( 0, min( 100, absint( $settings['overlay_opacity'] ) ) ) : 40; $hex = ltrim( $safe_overlay, '#' ); if ( strlen( $hex ) === 3 ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $r = hexdec( substr( $hex, 0, 2 ) ); $g = hexdec( substr( $hex, 2, 2 ) ); $b = hexdec( substr( $hex, 4, 2 ) ); $a = round( $opacity / 100, 2 ); $vars[] = '--aha-hs-overlay:rgba(' . $r . ',' . $g . ',' . $b . ',' . $a . ')'; } if ( empty( $vars ) ) { return ''; } $css = '.aha-hero-slider{' . implode( ';', $vars ) . '}'; // Mobile button colors — emitted as separate vars so per-slide desktop still cascades correctly. $mobile_hex_map = array( 'color_btn1_bg_mobile' => '--aha-hs-btn1-bg-mobile', 'color_btn1_text_mobile' => '--aha-hs-btn1-color-mobile', 'color_btn1_border_mobile' => '--aha-hs-btn1-border-mobile', 'color_btn2_bg_mobile' => '--aha-hs-btn2-bg-mobile', 'color_btn2_text_mobile' => '--aha-hs-btn2-color-mobile', 'color_btn2_border_mobile' => '--aha-hs-btn2-border-mobile', ); $mobile_vars = array(); foreach ( $mobile_hex_map as $key => $var ) { if ( ! empty( $settings[ $key ] ) ) { $safe = sanitize_hex_color( $settings[ $key ] ); if ( $safe ) { $mobile_vars[] = $var . ':' . $safe; } } } if ( isset( $settings['color_btn1_radius_mobile'] ) && '' !== (string) $settings['color_btn1_radius_mobile'] ) { $mobile_vars[] = '--aha-hs-btn1-radius-mobile:' . absint( $settings['color_btn1_radius_mobile'] ) . 'px'; } if ( isset( $settings['color_btn2_radius_mobile'] ) && '' !== (string) $settings['color_btn2_radius_mobile'] ) { $mobile_vars[] = '--aha-hs-btn2-radius-mobile:' . absint( $settings['color_btn2_radius_mobile'] ) . 'px'; } if ( ! empty( $mobile_vars ) ) { $css .= '@media(max-width:767px){.aha-hero-slider{' . implode( ';', $mobile_vars ) . '}}'; } return $css; } /** * Render slider HTML. * * @param array> $slides Slide data. * @param string $slider_id DOM id (unique). * @param array $config Keys: autoplay_speed, show_arrows, transition, infinite, progress, title_tag, instance_css_vars (map of --aha-hs-* = hex). Extensions may add keys via {@see 'aha_hero_slider_render_config'}. */ function aha_hero_slider_render( array $slides, $slider_id, array $config = array() ) { if ( empty( $slides ) ) { return; } $defaults = array( 'autoplay_speed' => 5000, 'show_arrows' => true, 'border_radius' => 0, 'transition' => 'slide', 'infinite' => 'loop', 'progress' => '', 'title_tag' => 'h2', 'instance_css_vars' => array(), ); $config = wp_parse_args( $config, $defaults ); $config['transition'] = aha_hero_slider_sanitize_transition_mode( (string) $config['transition'] ); $config['progress'] = aha_hero_slider_sanitize_progress_mode( (string) $config['progress'] ); $config['title_tag'] = aha_hero_slider_sanitize_title_heading_tag( (string) $config['title_tag'] ); $config['instance_css_vars'] = aha_hero_slider_sanitize_instance_css_vars( is_array( $config['instance_css_vars'] ) ? $config['instance_css_vars'] : array() ); $template = AHA_HERO_SLIDER_PATH . 'templates/frontend/slider.php'; if ( is_readable( $template ) ) { include $template; } }