current ) ) { $atts['aria-current'] = 'page'; } return $atts; } add_filter( 'nav_menu_link_attributes', 'bongoto_shop_menu_link_aria_current', 10, 4 ); /** Ensure wp_nav_menu gets a sensible fallback menu class. */ function bongoto_shop_nav_menu_args( $args ) { if ( empty( $args['menu_class'] ) ) { $args['menu_class'] = 'menu'; } return $args; } add_filter( 'wp_nav_menu_args', 'bongoto_shop_nav_menu_args' ); /** * ------------------------------------------------------------------------- * 2) Header / Footer hook points (no-op defaults to keep hook map visible) * ------------------------------------------------------------------------- */ /** * All custom hooks now follow the `bongoto_shop/...` namespace. */ function bongoto_shop_before_header() { /* reserved for child/pro overrides */ } add_action( 'bongoto_shop/before_header', 'bongoto_shop_before_header' ); function bongoto_shop_after_header() { /* reserved for child/pro overrides */ } add_action( 'bongoto_shop/after_header', 'bongoto_shop_after_header' ); function bongoto_shop_before_footer() { /* reserved for child/pro overrides */ } add_action( 'bongoto_shop/before_footer', 'bongoto_shop_before_footer' ); function bongoto_shop_after_footer() { /* reserved for child/pro overrides */ } add_action( 'bongoto_shop/after_footer', 'bongoto_shop_after_footer' ); /** Front-page hook slots. */ function bongoto_shop_front_before() { /* reserved */ } add_action( 'bongoto_shop/front_before', 'bongoto_shop_front_before' ); function bongoto_shop_front_after() { /* reserved */ } add_action( 'bongoto_shop/front_after', 'bongoto_shop_front_after' ); function bongoto_shop_front_before_hero() { /* reserved */ } add_action( 'bongoto_shop/front_before_hero', 'bongoto_shop_front_before_hero' ); function bongoto_shop_front_after_hero() { /* reserved */ } add_action( 'bongoto_shop/front_after_hero', 'bongoto_shop_front_after_hero' ); /** * Pro subscribe injector slot (theme renders a basic bar; * Pro plugin may hook here to output popup/advanced layout). */ function bongoto_shop_pro_footer_subscribe_slot() { /* noop in free */ } add_action( 'bongoto_shop/pro/footer_subscribe', 'bongoto_shop_pro_footer_subscribe_slot' ); /** * ------------------------------------------------------------------------- * 3) Header variants: expose choices via filters (Pro can extend) * ------------------------------------------------------------------------- */ /** * Available header variants (IDs). * * Pro plugin may extend: * add_filter( * 'bongoto_shop/header/allowed_variants', * fn( $v ) => array( 1, 2, 3, 4, 5 ) * ); */ function bongoto_shop_header_variants() { $variants = apply_filters( 'bongoto_shop/header/allowed_variants', array( 1 ) ); return array_values( array_unique( array_map( 'intval', (array) $variants ) ) ); } /** Human-friendly labels for Customizer. */ function bongoto_shop_header_variant_choices( $choices = array() ) { $choices = wp_parse_args( (array) $choices, array( '1' => __( 'Header 1 (Logo • Menu • Actions)', 'bongoto-shop' ), ) ); /** * Pro plugin can inject additional variant labels here. */ $choices = apply_filters( 'bongoto_shop/header/variant_choices', $choices ); return $choices; } /** Body class for header variant (e.g., bt-hv-1). */ function bongoto_shop_header_variant_body_class( $classes ) { // Later you may update this with a new Customizer setting. $variant = (int) get_theme_mod( 'bongoto_header_variant', 1 ); $classes[] = 'bt-hv-' . max( 1, $variant ); return $classes; } add_filter( 'body_class', 'bongoto_shop_header_variant_body_class' ); /** * ------------------------------------------------------------------------- * 4) Footer: columns / max columns (Pro may raise to 6) * ------------------------------------------------------------------------- */ /** Max columns default: 4 (free version). Pro may raise via filter. */ function bongoto_shop_footer_max_columns() { $max = 4; $max = (int) apply_filters( 'bongoto_shop/footer/max_columns', $max ); return max( 1, min( 6, $max ) ); } /** Current column count, clamped to valid range. */ function bongoto_shop_footer_current_columns() { $want = absint( get_theme_mod( 'bongoto_footer_columns', 4 ) ); $max = bongoto_shop_footer_max_columns(); $cols = max( 1, min( $want, $max ) ); /** Allow Pro to adjust/clamp. */ $cols = (int) apply_filters( 'bongoto_shop/footer/columns', $cols ); return max( 1, min( $cols, $max ) ); } /** * ------------------------------------------------------------------------- * 5) Front sections (safe defaults) * - If WooCommerce active: show a featured products grid. * - Otherwise: show latest posts. * Can be removed by unhooking from a child theme. * ------------------------------------------------------------------------- */ function bongoto_shop_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-shop' ) . '

'; 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-shop' ) . '

'; echo '
'; while ( $posts->have_posts() ) { $posts->the_post(); echo ''; } echo '
'; wp_reset_postdata(); } } } add_action( 'bongoto_shop/front_sections', 'bongoto_shop_front_sections_default' ); /** * ------------------------------------------------------------------------- * 6) WooCommerce cart fragments (update cart count in header via AJAX) * ------------------------------------------------------------------------- */ function bongoto_shop_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_shop_custom_logo_attr', 20 ); /** * Output lightweight identity CSS for all header variants. * This ensures the Site Identity toggles affect extra header templates too. */ function bongoto_shop_site_identity_css() { $show_title = get_theme_mod( 'bongoto_shop_show_title_text', null ); if ( null === $show_title ) { $show_title = get_theme_mod( 'bongoto_show_title_text', true ); } $show_tagline = get_theme_mod( 'bongoto_shop_show_tagline_text', null ); if ( null === $show_tagline ) { $show_tagline = get_theme_mod( 'bongoto_show_tagline_text', false ); } $logo_h = get_theme_mod( 'bongoto_shop_logo_max_height', '' ); if ( '' === $logo_h || null === $logo_h ) { $logo_h = get_theme_mod( 'bongoto_logo_max_height', 40 ); } $logo_h = absint( $logo_h ); echo "\n\n"; } add_action( 'wp_head', 'bongoto_shop_site_identity_css', 25 ); /** * ------------------------------------------------------------------------- * 8) Login redirect helper * - If user logs in with ?bongoto_shop_redirect=..., redirect there after login. * ------------------------------------------------------------------------- */ function bongoto_shop_login_redirect( $redirect_to, $request, $user ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! empty( $_REQUEST['bongoto_shop_redirect'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $target = esc_url_raw( wp_unslash( $_REQUEST['bongoto_shop_redirect'] ) ); if ( $target ) { return $target; } } return $redirect_to; } add_filter( 'login_redirect', 'bongoto_shop_login_redirect', 10, 3 );