widget_cssclass = 'woocommerce widget_brand_nav widget_layered_nav'; $this->widget_description = __( 'Shows brands in a widget which lets you narrow down the list of products when viewing products.', 'woocommerce' ); $this->widget_id = 'woocommerce_brand_nav'; $this->widget_name = __( 'WooCommerce Brand Layered Nav', 'woocommerce' ); add_filter( 'woocommerce_product_subcategories_args', array( $this, 'filter_out_cats' ) ); /* Create the widget. */ parent::__construct(); } /** * Filter out all categories and not display them * * @param array $cat_args Category arguments. */ public function filter_out_cats( $cat_args ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! empty( $_GET['filter_product_brand'] ) ) { return array( 'taxonomy' => '' ); } return $cat_args; } /** * Return the currently viewed taxonomy name. * * @return string */ protected function get_current_taxonomy() { return is_tax() ? get_queried_object()->taxonomy : ''; } /** * Return the currently viewed term ID. * * @return int */ protected function get_current_term_id() { return absint( is_tax() ? get_queried_object()->term_id : 0 ); } /** * Return the currently viewed term slug. * * @return int */ protected function get_current_term_slug() { return absint( is_tax() ? get_queried_object()->slug : 0 ); } /** * Widget function. * * @see WP_Widget * * @param array $args Arguments. * @param array $instance Widget instance. * @return void */ public function widget( $args, $instance ) { $attribute_array = array(); $attribute_taxonomies = wc_get_attribute_taxonomies(); if ( ! empty( $attribute_taxonomies ) ) { foreach ( $attribute_taxonomies as $tax ) { if ( taxonomy_exists( wc_attribute_taxonomy_name( $tax->attribute_name ) ) ) { $attribute_array[ $tax->attribute_name ] = $tax->attribute_name; } } } if ( ! is_post_type_archive( 'product' ) && ! is_tax( array_merge( is_array( $attribute_array ) ? $attribute_array : array(), array( 'product_cat', 'product_tag' ) ) ) ) { return; } $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); $current_term = $attribute_array && is_tax( $attribute_array ) ? get_queried_object()->term_id : ''; $current_tax = $attribute_array && is_tax( $attribute_array ) ? get_queried_object()->taxonomy : ''; /** * Filter the widget's title. * * @since 9.4.0 * * @param string $title Widget title * @param array $instance The settings for the particular instance of the widget. * @param string $woo_widget_idbase The widget's id base. */ $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); $taxonomy = 'product_brand'; $display_type = isset( $instance['display_type'] ) ? $instance['display_type'] : 'list'; if ( ! taxonomy_exists( $taxonomy ) ) { return; } // Get only parent terms. Methods will recursively retrieve children. $terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => true, 'parent' => 0, ) ); if ( empty( $terms ) ) { return; } ob_start(); $this->widget_start( $args, $instance ); if ( 'dropdown' === $display_type ) { $found = $this->layered_nav_dropdown( $terms, $taxonomy ); } else { $found = $this->layered_nav_list( $terms, $taxonomy ); } $this->widget_end( $args ); // Force found when option is selected - do not force found on taxonomy attributes. if ( ! is_tax() && is_array( $_chosen_attributes ) && array_key_exists( $taxonomy, $_chosen_attributes ) ) { $found = true; } if ( ! $found ) { ob_end_clean(); } else { echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput } } /** * Update function. * * @see WP_Widget->update * * @param array $new_instance The new settings for the particular instance of the widget. * @param array $old_instance The old settings for the particular instance of the widget. * @return array */ public function update( $new_instance, $old_instance ) { global $woocommerce; if ( empty( $new_instance['title'] ) ) { $new_instance['title'] = __( 'Brands', 'woocommerce' ); } $instance['title'] = wp_strip_all_tags( stripslashes( $new_instance['title'] ) ); $instance['display_type'] = stripslashes( $new_instance['display_type'] ); return $instance; } /** * Form function. * * @see WP_Widget->form * * @param array $instance Widget instance. * @return void */ public function form( $instance ) { global $woocommerce; if ( ! isset( $instance['display_type'] ) ) { $instance['display_type'] = 'list'; } ?>
$data ) { if ( $name === $taxonomy ) { continue; } $filter_name = sanitize_title( str_replace( 'pa_', '', $name ) ); if ( ! empty( $data['terms'] ) ) { $link = add_query_arg( 'filter_' . $filter_name, implode( ',', $data['terms'] ), $link ); } if ( 'or' === $data['query_type'] ) { $link = add_query_arg( 'query_type_' . $filter_name, 'or', $link ); } } } // phpcs:enable WordPress.Security.NonceVerification.Recommended return esc_url( $link ); } /** * Gets the currently selected attributes * * @return array */ public function get_chosen_attributes() { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! empty( $_GET['filter_product_brand'] ) ) { $filter_product_brand = wc_clean( wp_unslash( $_GET['filter_product_brand'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended return array_map( 'intval', explode( ',', $filter_product_brand ) ); } return array(); } /** * Show dropdown layered nav. * * @param array $terms Terms. * @param string $taxonomy Taxonomy. * @param int $depth Depth. * @return bool Will nav display? */ protected function layered_nav_dropdown( $terms, $taxonomy, $depth = 0 ) { $found = false; if ( $taxonomy !== $this->get_current_taxonomy() ) { $term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, 'or' ); $_chosen_attributes = $this->get_chosen_attributes(); if ( 0 === $depth ) { echo ''; wc_enqueue_js( " jQuery( '.wc-brand-dropdown-layered-nav-" . esc_js( $taxonomy ) . "' ).change( function() { var slug = jQuery( this ).val(); location.href = '" . preg_replace( '%\/page\/[0-9]+%', '', str_replace( array( '&', '%2C' ), array( '&', ',' ), esc_js( add_query_arg( 'filtering', '1', $link ) ) ) ) . '&filter_' . esc_js( $taxonomy ) . "=' + jQuery( '.wc-brand-dropdown-layered-nav-" . esc_js( $taxonomy ) . "' ).val(); }); " ); } } return $found; } /** * Show list based layered nav. * * @param array $terms Terms. * @param string $taxonomy Taxonomy. * @param int $depth Depth. * @return bool Will nav display? */ protected function layered_nav_list( $terms, $taxonomy, $depth = 0 ) { // List display. echo '