current ) ) { $atts['aria-current'] = 'page'; } return $atts; } add_filter( 'nav_menu_link_attributes', 'bongoto_menu_link_aria_current', 10, 4 ); /** Ensure wp_nav_menu gets a sensible fallback menu class. */ function bongoto_nav_menu_args( $args ) { if ( empty( $args['menu_class'] ) ) { $args['menu_class'] = 'menu'; } return $args; } add_filter( 'wp_nav_menu_args', 'bongoto_nav_menu_args' ); /** * ------------------------------------------------------------------------- * 2) Header / Footer hook points (no-op defaults to keep hook map visible) * ------------------------------------------------------------------------- */ function bongoto_before_header() { /* reserved for child/pro overrides */ } add_action( 'bongoto/before_header', 'bongoto_before_header' ); function bongoto_after_header() { /* reserved for child/pro overrides */ } add_action( 'bongoto/after_header', 'bongoto_after_header' ); function bongoto_before_footer() { /* reserved for child/pro overrides */ } add_action( 'bongoto/before_footer', 'bongoto_before_footer' ); function bongoto_after_footer() { /* reserved for child/pro overrides */ } add_action( 'bongoto/after_footer', 'bongoto_after_footer' ); /** Front-page hook slots. */ function bongoto_front_before() { /* reserved */ } add_action( 'bongoto/front_before', 'bongoto_front_before' ); function bongoto_front_after() { /* reserved */ } add_action( 'bongoto/front_after', 'bongoto_front_after' ); function bongoto_front_before_hero() { /* reserved */ } add_action( 'bongoto/front_before_hero', 'bongoto_front_before_hero' ); function bongoto_front_after_hero() { /* reserved */ } add_action( 'bongoto/front_after_hero', 'bongoto_front_after_hero' ); /** * Pro subscribe injector slot (theme renders a simple bar; * Pro plugin may hook here to output popup/advanced layout). */ function bongoto_pro_footer_subscribe_slot() { /* noop in free */ } add_action( 'bongoto/pro/footer_subscribe', 'bongoto_pro_footer_subscribe_slot' ); /** * ------------------------------------------------------------------------- * 3) Header variants: expose choices via filters (Pro can extend) * ------------------------------------------------------------------------- */ /** * Available header variants (IDs) – theme ships v1; Pro adds 2–5. * Filter in plugin: add_filter('bongoto/pro/header_variants', fn($v)=>array_merge($v,[2,3,4,5])); */ function bongoto_header_variants() { $variants = array( 1 ); $variants = apply_filters( 'bongoto/pro/header_variants', $variants ); return array_values( array_unique( array_map( 'intval', (array) $variants ) ) ); } /** * Human labels for Customizer (theme shows only v1 unless Pro adds). */ function bongoto_header_variant_choices( $choices = array() ) { $choices = wp_parse_args( (array) $choices, array( '1' => __( 'Header 1 (Logo • Menu • Actions)', 'bongoto' ), ) ); $choices = apply_filters( 'bongoto/pro/header_variant_choices', $choices ); return $choices; } /** * Body class for header variant (e.g., bt-hv-1). */ function bongoto_header_variant_body_class( $classes ) { $variant = (int) get_theme_mod( 'bongoto_header_variant', 1 ); $classes[] = 'bt-hv-' . max( 1, $variant ); return $classes; } add_filter( 'body_class', 'bongoto_header_variant_body_class' ); /** * ------------------------------------------------------------------------- * 4) Footer: columns / max columns (Pro may raise to 6) * ------------------------------------------------------------------------- */ /** * Max columns default 4 (free); Pro can raise via filter. */ function bongoto_footer_max_columns() { $max = 4; $max = (int) apply_filters( 'bongoto/footer/max_columns', $max ); return max( 1, min( 6, $max ) ); } /** * Current columns clamped [1..max]. */ function bongoto_footer_current_columns() { $want = absint( get_theme_mod( 'bongoto_footer_columns', 4 ) ); $max = bongoto_footer_max_columns(); $cols = max( 1, min( $want, $max ) ); /** * Let Pro clamp/adjust if needed. */ $cols = (int) apply_filters( 'bongoto/footer/columns', $cols ); return max( 1, min( $cols, $max ) ); } /** * ------------------------------------------------------------------------- * 5) Front sections (safe defaults) * - If WooCommerce active: show a small featured products grid. * - Otherwise: show latest posts. * Can be removed by unhooking from a child theme. * ------------------------------------------------------------------------- */ function bongoto_front_sections_default() { if ( is_front_page() && is_main_query() ) { // WooCommerce Featured products block. if ( class_exists( 'WooCommerce' ) ) { $products = new WP_Query( array( 'post_type' => 'product', 'posts_per_page' => 8, 'meta_key' => '_featured', 'meta_value' => 'yes', 'no_found_rows' => true, ) ); if ( $products->have_posts() ) { echo '
'; echo '

' . esc_html__( 'Featured Products', 'bongoto' ) . '

'; echo '
'; wp_reset_postdata(); return; } wp_reset_postdata(); } // Fallback: Latest posts grid. $posts = new WP_Query( array( 'posts_per_page' => 6, 'ignore_sticky_posts' => true, 'no_found_rows' => true, ) ); if ( $posts->have_posts() ) { echo '
'; echo '

' . esc_html__( 'Latest Posts', 'bongoto' ) . '

'; echo '
'; while ( $posts->have_posts() ) { $posts->the_post(); echo ''; } echo '
'; wp_reset_postdata(); } } } add_action( 'bongoto/front_sections', 'bongoto_front_sections_default' ); /** * ------------------------------------------------------------------------- * 6) WooCommerce cart fragments (update cart count in header via AJAX) * - Guarded to avoid fatal if Woo is missing. * - If you already add a fragment elsewhere, this is harmless. * ------------------------------------------------------------------------- */ function bongoto_wc_cart_count_fragment( $fragments ) { if ( ! class_exists( 'WooCommerce' ) || ! function_exists( 'WC' ) ) { return $fragments; } $count = ( WC()->cart ) ? (int) WC()->cart->get_cart_contents_count() : 0; ob_start(); ?> 0 ) { // Insert/replace style attribute to enforce max-height. $html = preg_replace( '/(]+style=")([^"]*)(")/i', '$1$2 max-height:' . $max . 'px; height:auto; width:auto;$3', $html, 1 ); } return $html; } add_filter( 'get_custom_logo', 'bongoto_custom_logo_attr', 20 ); /** * ------------------------------------------------------------------------- * 8) Login redirect helper * - If a user clicks "Upload" while logged-out, they go to login; on success * return them to the upload/new-product destination. * ------------------------------------------------------------------------- */ function bongoto_login_redirect( $redirect_to, $request, $user ) { if ( ! empty( $_REQUEST['bongoto_redirect'] ) ) { $target = esc_url_raw( wp_unslash( $_REQUEST['bongoto_redirect'] ) ); if ( $target ) { return $target; } } return $redirect_to; } add_filter( 'login_redirect', 'bongoto_login_redirect', 10, 3 );