'wines', 'redirect_collection_root' => 1, 'redirect_product_root' => 0, 'product_redirect_target' => '', 'custom_redirects' => array(), 'update_continue_shopping' => 1, 'enable_c7_custom_routes' => 0, 'branding_enabled' => 1, 'brand_scope' => array( 'buttons' => 1, 'text' => 1, 'forms' => 1, 'cart' => 1, ), 'theme_primary' => '', 'theme_button_text' => '', 'theme_text' => '', 'theme_link' => '', 'theme_heading_font' => '', 'theme_body_font' => '', 'theme_button_radius' => '', 'brand' => self::default_brand(), 'hide_floating_cart_mobile' => 0, 'cart_box_tone' => 'auto', 'show_admin_notices' => 1, // Optional front-end credit link. Opt-in, default OFF (WordPress.org Guideline 10). 'frontend_credit' => 0, // Shop Layout — defaults match Commerce7 CDN (commerce7.css). 'layout_enabled' => 1, 'layout_card_style' => 'horizontal', 'layout_cols_desktop' => 2, 'layout_cols_tablet' => 2, 'layout_cols_mobile' => 1, 'layout_col_gap' => 30, 'layout_row_gap' => 80, 'layout_page_width' => 1300, 'layout_pdp_preset' => 'classic', 'layout_builder_mode' => 'auto', // Fonts. 'font_heading_key' => 'google:DM Sans', 'font_body_key' => 'google:DM Sans', 'google_fonts_url' => '', 'custom_fonts' => array(), ); } /** * Default Commerce7 brand CSS variable values. * * @return array */ public static function default_brand() { return array( 'primary_color' => '', 'primary_color_dark' => '', 'primary_color_focus' => '', 'primary_button_bg' => '', 'primary_button_bg_hover' => '', 'primary_button_text_color' => '', 'alt_button_bg' => '', 'alt_button_bg_hover' => '', 'alt_button_text_color' => '', 'text_color' => '', 'alt_text_color' => '', 'link_color' => '', 'header_text_color' => '', 'heading_text_color' => '', 'heading_font_family' => '', 'font_family' => '', 'font_size' => '18px', 'button_border_radius' => '', 'field_border_radius' => '', 'field_border_color' => '', 'field_focus_color' => '', 'cart_count_bg' => '', 'cart_count_text_color' => '', 'bg_alt' => '', 'block_bg' => '', 'block_border_color' => '', 'block_border_radius' => '', 'modal_shadow' => '', 'overlay_bg' => '', ); } /** * Map brand keys to CSS custom properties. * * @return array */ public static function brand_css_map() { return array( 'primary_color' => '--c7-primary-color', 'primary_color_dark' => '--c7-primary-color-dark', 'primary_color_focus' => '--c7-primary-color-focus', 'primary_button_bg' => '--c7-primary-button-bg', 'primary_button_bg_hover' => '--c7-primary-button-bg-hover', 'primary_button_text_color' => '--c7-primary-button-text-color', 'alt_button_bg' => '--c7-alt-button-bg', 'alt_button_bg_hover' => '--c7-alt-button-bg-hover', 'alt_button_text_color' => '--c7-alt-button-text-color', 'text_color' => '--c7-body-text-color', 'alt_text_color' => '--c7-alt-text-color', 'link_color' => '--c7-link-color', 'header_text_color' => '--c7-header-text-color', 'heading_text_color' => '--c7-heading-text-color', 'heading_font_family' => '--c7-heading-font-family', 'font_family' => '--c7-font-family', 'font_size' => '--c7-font-size', 'button_border_radius' => '--c7-button-border-radius', 'field_border_radius' => '--c7-field-border-radius', 'field_border_color' => '--c7-field-border-color', 'field_focus_color' => '--c7-field-focus-color', 'cart_count_bg' => '--c7-cart-count-bg', 'cart_count_text_color' => '--c7-cart-count-text-color', 'bg_alt' => '--c7-bg-alt', 'block_bg' => '--c7-block-bg', 'block_border_color' => '--c7-block-border-color', 'block_border_radius' => '--c7-block-border-radius', 'modal_shadow' => '--c7-modal-shadow', 'overlay_bg' => '--c7-overlay-bg', ); } /** * Get merged settings. * * @return array */ public static function get() { $stored = get_option( C7DBT_OPTION_KEY, array() ); if ( ! is_array( $stored ) ) { $stored = array(); } $defaults = self::defaults(); $merged = array_merge( $defaults, $stored ); $merged['brand'] = array_merge( self::default_brand(), isset( $stored['brand'] ) && is_array( $stored['brand'] ) ? $stored['brand'] : array() ); $merged['brand_scope'] = array_merge( $defaults['brand_scope'], isset( $stored['brand_scope'] ) && is_array( $stored['brand_scope'] ) ? $stored['brand_scope'] : array() ); if ( empty( $merged['custom_redirects'] ) || ! is_array( $merged['custom_redirects'] ) ) { $merged['custom_redirects'] = array(); } if ( empty( $merged['custom_fonts'] ) || ! is_array( $merged['custom_fonts'] ) ) { $merged['custom_fonts'] = array(); } $merged['default_collection_slug'] = C7DBT_Helpers::normalize_collection_slug( $merged['default_collection_slug'] ); return $merged; } /** * Update settings (partial merge). * * @param array $partial Partial settings. * @return array */ public static function update( array $partial ) { $current = self::get(); if ( isset( $partial['brand'] ) && is_array( $partial['brand'] ) ) { $partial['brand'] = array_merge( $current['brand'], $partial['brand'] ); } if ( isset( $partial['brand_scope'] ) && is_array( $partial['brand_scope'] ) ) { $partial['brand_scope'] = array_merge( $current['brand_scope'], $partial['brand_scope'] ); } $new = array_merge( $current, $partial ); update_option( C7DBT_OPTION_KEY, $new, false ); return $new; } /** * Sanitize settings from admin POST. * * @param array $input Raw input. * @return array */ public static function sanitize( array $input ) { $out = self::get(); if ( isset( $input['default_collection_slug'] ) ) { $out['default_collection_slug'] = C7DBT_Helpers::normalize_collection_slug( $input['default_collection_slug'] ); } $out['redirect_collection_root'] = empty( $input['redirect_collection_root'] ) ? 0 : 1; $out['redirect_product_root'] = empty( $input['redirect_product_root'] ) ? 0 : 1; if ( isset( $input['product_redirect_target'] ) ) { $out['product_redirect_target'] = C7DBT_Helpers::sanitize_slug( $input['product_redirect_target'] ); } $out['update_continue_shopping'] = empty( $input['update_continue_shopping'] ) ? 0 : 1; $out['enable_c7_custom_routes'] = empty( $input['enable_c7_custom_routes'] ) ? 0 : 1; $out['branding_enabled'] = empty( $input['branding_enabled'] ) ? 0 : 1; $out['hide_floating_cart_mobile'] = empty( $input['hide_floating_cart_mobile'] ) ? 0 : 1; // Only flip these when saving the Settings screen (checkboxes omitted when unchecked). if ( isset( $input['c7dbt_form'] ) && 'settings' === $input['c7dbt_form'] ) { $out['show_admin_notices'] = empty( $input['show_admin_notices'] ) ? 0 : 1; $out['frontend_credit'] = empty( $input['frontend_credit'] ) ? 0 : 1; } if ( isset( $input['cart_box_tone'] ) ) { $tone = sanitize_key( $input['cart_box_tone'] ); $out['cart_box_tone'] = in_array( $tone, array( 'auto', 'light', 'dark' ), true ) ? $tone : 'auto'; } if ( isset( $input['brand_scope'] ) && is_array( $input['brand_scope'] ) ) { foreach ( array( 'buttons', 'text', 'forms', 'cart' ) as $scope ) { $out['brand_scope'][ $scope ] = empty( $input['brand_scope'][ $scope ] ) ? 0 : 1; } } elseif ( isset( $input['c7dbt_form'] ) && 'brand' === $input['c7dbt_form'] ) { // Checkboxes omitted when unchecked. $out['brand_scope'] = array( 'buttons' => empty( $input['brand_scope']['buttons'] ) ? 0 : 1, 'text' => empty( $input['brand_scope']['text'] ) ? 0 : 1, 'forms' => empty( $input['brand_scope']['forms'] ) ? 0 : 1, 'cart' => empty( $input['brand_scope']['cart'] ) ? 0 : 1, ); } foreach ( array( 'theme_primary', 'theme_button_text', 'theme_text', 'theme_link' ) as $color_key ) { if ( isset( $input[ $color_key ] ) ) { $out[ $color_key ] = C7DBT_Helpers::sanitize_hex_color( $input[ $color_key ] ); } } foreach ( array( 'theme_heading_font', 'theme_body_font', 'theme_button_radius' ) as $text_key ) { if ( isset( $input[ $text_key ] ) ) { $out[ $text_key ] = sanitize_text_field( $input[ $text_key ] ); } } if ( isset( $input['brand'] ) && is_array( $input['brand'] ) ) { $brand_defaults = self::default_brand(); foreach ( $brand_defaults as $key => $default ) { if ( ! array_key_exists( $key, $input['brand'] ) ) { continue; } $val = $input['brand'][ $key ]; if ( false !== strpos( $key, 'font' ) || 'font_size' === $key || false !== strpos( $key, 'radius' ) || 'modal_shadow' === $key || 'overlay_bg' === $key ) { $out['brand'][ $key ] = sanitize_text_field( $val ); } else { $out['brand'][ $key ] = C7DBT_Helpers::sanitize_hex_color( $val ); } } } if ( isset( $input['custom_redirects'] ) && is_array( $input['custom_redirects'] ) ) { $clean = array(); foreach ( $input['custom_redirects'] as $row ) { if ( empty( $row['from'] ) || empty( $row['to'] ) ) { continue; } $clean[] = array( 'from' => '/' . ltrim( C7DBT_Helpers::sanitize_slug( $row['from'] ), '/' ), 'to' => '/' . ltrim( C7DBT_Helpers::sanitize_slug( $row['to'] ), '/' ), ); } $out['custom_redirects'] = $clean; } // Shop Layout. if ( isset( $input['c7dbt_form'] ) && 'layout' === $input['c7dbt_form'] ) { $out['layout_enabled'] = empty( $input['layout_enabled'] ) ? 0 : 1; } elseif ( isset( $input['layout_enabled'] ) ) { $out['layout_enabled'] = empty( $input['layout_enabled'] ) ? 0 : 1; } if ( isset( $input['layout_card_style'] ) ) { $style = sanitize_key( $input['layout_card_style'] ); $out['layout_card_style'] = in_array( $style, array( 'catalog', 'horizontal', 'auto' ), true ) ? $style : 'horizontal'; } foreach ( array( 'layout_cols_desktop', 'layout_cols_tablet', 'layout_cols_mobile' ) as $col_key ) { if ( isset( $input[ $col_key ] ) ) { $out[ $col_key ] = max( 1, min( 4, absint( $input[ $col_key ] ) ) ); } } foreach ( array( 'layout_col_gap', 'layout_row_gap' ) as $gap_key ) { if ( isset( $input[ $gap_key ] ) ) { $out[ $gap_key ] = max( 0, min( 120, absint( $input[ $gap_key ] ) ) ); } } if ( isset( $input['layout_page_width'] ) ) { $out['layout_page_width'] = max( 800, min( 1600, absint( $input['layout_page_width'] ) ) ); } if ( isset( $input['layout_pdp_preset'] ) ) { $pdp = sanitize_key( $input['layout_pdp_preset'] ); $out['layout_pdp_preset'] = in_array( $pdp, array( 'classic', 'balanced', 'stacked', 'centered' ), true ) ? $pdp : 'classic'; } if ( isset( $input['layout_builder_mode'] ) ) { $mode = sanitize_key( $input['layout_builder_mode'] ); $allowed = array( 'auto', 'gutenberg', 'elementor', 'divi', 'bricks', 'oxygen', 'off' ); $out['layout_builder_mode'] = in_array( $mode, $allowed, true ) ? $mode : 'auto'; } // Fonts. if ( isset( $input['font_heading_key'] ) ) { $out['font_heading_key'] = sanitize_text_field( $input['font_heading_key'] ); } if ( isset( $input['font_body_key'] ) ) { $out['font_body_key'] = sanitize_text_field( $input['font_body_key'] ); } if ( isset( $input['google_fonts_url'] ) ) { $url = esc_url_raw( $input['google_fonts_url'] ); $host = $url ? wp_parse_url( $url, PHP_URL_HOST ) : ''; $out['google_fonts_url'] = ( $url && in_array( $host, array( 'fonts.googleapis.com', 'fonts.gstatic.com' ), true ) ) ? $url : ''; } return $out; } }