Created
August 27, 2018 06:56
-
-
Save shrimp2t/9fbd809cd5dcd30be41a8eadd7c5738a to your computer and use it in GitHub Desktop.
WC filter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ($, window, document) { | |
"use strict"; | |
var customifyWCFiterXHR = false; | |
$.fn.customifyOffCanvas = function ( options ) { | |
var opts = $.extend({ | |
selector : '.woocommerce-listing', | |
}, options ); | |
var updateURL = function( url ) { | |
// IE only supports pushState() in v10 and above, so don't bother if those conditions aren't met. | |
if ( ! window.history.pushState ) { | |
return; | |
} | |
history.pushState( null, null, url ); | |
}; | |
var offCanvasFilter = function( options, $el ){ | |
/* | |
$el.on( 'click', '.woocommerce-widget-layered-nav-list li a', function(e){ | |
e.preventDefault(); | |
var url = $( this ).attr( 'href' ) || false; | |
if ( url ) { | |
ajax_request( url ); | |
} | |
} ); | |
*/ | |
$( '.customify-wc-filter-form input', $el ).on( 'change', function(e){ | |
var data = {}; | |
var form = $( '.customify-wc-filter-form' ); | |
$( 'input', form ).each( function(){ | |
var input = $( this ); | |
var input_type = input.attr( 'type' ) || 'text'; | |
var name = false; | |
switch ( input_type ) { | |
case 'checkbox': | |
if ( input.is(':checked') ) { | |
name = $( this ).attr( 'data-name' ) || false; | |
if ( name ) { | |
if ( typeof data[ name ] === "undefined" ) { | |
data[ name ] = []; | |
} | |
} | |
data[ name ].push( $( this ).val() ); | |
} | |
break; | |
case 'hidden': | |
case 'text': | |
name = $( this ).attr( 'name' ) || false; | |
if ( name ) { | |
if ( typeof data[ name ] === "undefined" ) { | |
data[ name ] = input.val(); | |
} | |
} | |
break; | |
} | |
} ); | |
var args = []; | |
$.each( data, function( key, values ){ | |
var string = ''; | |
if ( typeof values === 'array' || typeof values === 'object' ) { | |
string = values.join(','); | |
} else { | |
string = values; | |
} | |
args.push( key+'='+encodeURI( string ) ); | |
} ); | |
var sep = Customify_Pro_JS.wc_filter.shop.indexOf('?') > -1 ? '&' : '?'; | |
var query_url = Customify_Pro_JS.wc_filter.shop+sep+ args.join('&'); | |
ajax_request( query_url ); | |
} ); | |
function ajax_request( desturl ){ | |
console.log( 'Query URL', desturl ); | |
// decode url to prevent error | |
// desturl = decodeURIComponent(desturl); | |
// desturl = desturl.replace(/^(?:\/\/|[^\/]+)*\//, "/"); | |
if ( customifyWCFiterXHR ) { | |
customifyWCFiterXHR.abort(); | |
customifyWCFiterXHR = false; | |
} | |
updateURL( desturl ); | |
// ajax call | |
customifyWCFiterXHR = $.ajax({ | |
// params | |
url : desturl, | |
dataType : 'html', | |
success : function (data) { | |
var $data = $( data ); | |
var obj; | |
if ( $( opts.selector, $data ).length ) { | |
$( opts.selector ).html( $( opts.selector, $data ) ); | |
} | |
}, | |
error: function (req) { | |
} | |
}); | |
} | |
}; | |
return this.each(function() { | |
return new offCanvasFilter( options, $( this ) ); | |
}); | |
} | |
})( jQuery, window, document ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Layered nav widget | |
* | |
* @package WooCommerce/Widgets | |
* @version 2.6.0 | |
*/ | |
defined( 'ABSPATH' ) || exit; | |
require_once ABSPATH.'/wp-admin/includes/class-walker-category-checklist.php'; | |
class Customify_Walker_Category_Checklist extends Walker_Category_Checklist { | |
/** | |
* Start the element output. | |
* | |
* @see Walker::start_el() | |
* | |
* @since 2.5.1 | |
* | |
* @param string $output Used to append additional content (passed by reference). | |
* @param object $category The current term object. | |
* @param int $depth Depth of the term in reference to parents. Default 0. | |
* @param array $args An array of arguments. @see wp_terms_checklist() | |
* @param int $id ID of the current term. | |
*/ | |
public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) { | |
if ( empty( $args['taxonomy'] ) ) { | |
$taxonomy = 'category'; | |
} else { | |
$taxonomy = $args['taxonomy']; | |
} | |
switch ( $taxonomy ) { | |
case 'product_cat': case 'product_tag': | |
$name = 'filter_'.$taxonomy; | |
break; | |
case 'category': | |
$name = 'post_category'; | |
break; | |
default: | |
$name = 'filter_'.str_replace('pa_', '', $taxonomy); | |
} | |
$args['popular_cats'] = empty( $args['popular_cats'] ) ? array() : $args['popular_cats']; | |
$class = in_array( $category->term_id, $args['popular_cats'] ) ? ' class="popular-category"' : ''; | |
$args['selected_cats'] = empty( $args['selected_cats'] ) ? array() : $args['selected_cats']; | |
if ( ! empty( $args['list_only'] ) ) { | |
$aria_checked = 'false'; | |
$inner_class = 'category'; | |
if ( in_array( $category->term_id, $args['selected_cats'] ) ) { | |
$inner_class .= ' selected'; | |
$aria_checked = 'true'; | |
} | |
/** This filter is documented in wp-includes/category-template.php */ | |
$output .= "\n" . '<li' . $class . '>' . | |
'<div class="' . $inner_class . '" data-term-id=' . $category->slug . | |
' tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '">' . | |
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</div>'; | |
} else { | |
/** This filter is documented in wp-includes/category-template.php */ | |
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" . | |
'<label class="selectit"><input value="' . $category->slug . '" type="checkbox" data-name="'.esc_attr( $name ).'" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->slug . '"' . | |
checked( in_array( $category->slug, $args['selected_cats'] ), true, false ) . | |
disabled( empty( $args['disabled'] ), false, false ) . ' /> ' . | |
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</label>'; | |
} | |
} | |
} | |
/** | |
* Widget layered nav class. | |
* @see WC_Widget_Layered_Nav | |
*/ | |
class Customify_Pro_WC_Widget_Filter extends WC_Widget { | |
/** | |
* Constructor. | |
*/ | |
public function __construct() { | |
$this->widget_cssclass = 'customify-wc-filter woocommerce'; | |
$this->widget_description = __( 'Display a filter products in your store.', 'woocommerce' ); | |
$this->widget_id = 'customify_wc_filter'; | |
$this->widget_name = __( 'Customify Woocommerce Filter', 'woocommerce' ); | |
parent::__construct(); | |
} | |
/** | |
* Updates a particular instance of a widget. | |
* | |
* @see WP_Widget->update | |
* | |
* @param array $new_instance New Instance. | |
* @param array $old_instance Old Instance. | |
* | |
* @return array | |
*/ | |
public function update( $new_instance, $old_instance ) { | |
$this->init_settings(); | |
return parent::update( $new_instance, $old_instance ); | |
} | |
/** | |
* Outputs the settings update form. | |
* | |
* @see WP_Widget->form | |
* | |
* @param array $instance Instance. | |
*/ | |
public function form( $instance ) { | |
$this->init_settings(); | |
parent::form( $instance ); | |
} | |
/** | |
* Init settings after post types are registered. | |
*/ | |
public function init_settings() { | |
$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_label; | |
} | |
} | |
} | |
$attribute_array = array_merge( array( 'product_cat' => __( 'Categories', 'woocommerce' ), | |
'product_tag' => __( 'Tags', 'woocommerce' ) ), | |
$attribute_array, | |
array( | |
'stock_status' => __( 'Stock status', 'woocommerce' ), | |
'on_sale' => __( 'On Sale', 'woocommerce' ), | |
'_weight' => __( 'Weight', 'woocommerce' ), | |
'_length' => __( 'Length', 'woocommerce' ), | |
'_width' => __( 'Width', 'woocommerce' ), | |
'_height' => __( 'Height', 'woocommerce' ), | |
) | |
); | |
$this->settings = array( | |
'title' => array( | |
'type' => 'text', | |
'std' => __( 'Filter by', 'woocommerce' ), | |
'label' => __( 'Title', 'woocommerce' ), | |
), | |
'data_type' => array( | |
'type' => 'select', | |
'std' => '', | |
'label' => __( 'Filter Type', 'woocommerce' ), | |
'options' => $attribute_array, | |
), | |
'query_type' => array( | |
'type' => 'select', | |
'std' => 'and', | |
'label' => __( 'Query type', 'woocommerce' ), | |
'options' => array( | |
'and' => __( 'AND', 'woocommerce' ), | |
'or' => __( 'OR', 'woocommerce' ), | |
), | |
), | |
); | |
} | |
/** | |
* Output an unordered list of checkbox input elements labelled with term names. | |
* | |
* Taxonomy-independent version of wp_category_checklist(). | |
* | |
* @see wp_terms_checklist | |
* | |
* | |
* @param array|string $args { | |
* Optional. Array or string of arguments for generating a terms checklist. Default empty array. | |
* | |
* @type int $descendants_and_self ID of the category to output along with its descendants. | |
* Default 0. | |
* @type array $selected_cats List of categories to mark as checked. Default false. | |
* Default false. | |
* @type object $walker Walker object to use to build the output. | |
* Default is a Walker_Category_Checklist instance. | |
* @type string $taxonomy Taxonomy to generate the checklist for. Default 'category'. | |
* the top of the list. Default true. | |
* @type bool $echo Whether to echo the generated markup. False to return the markup instead | |
* of echoing it. Default true. | |
* } | |
*/ | |
function wp_terms_checklist( $args = array() ) { | |
$defaults = array( | |
'selected_cats' => false, | |
'walker' => null, | |
'taxonomy' => 'category', | |
'echo' => true, | |
); | |
/** | |
* Filters the taxonomy terms checklist arguments. | |
* | |
* @since 3.4.0 | |
* | |
* @see wp_terms_checklist() | |
* | |
* @param array $args An array of arguments. | |
* @param int $post_id The post ID. | |
*/ | |
$params = apply_filters( 'wp_terms_checklist_args', $args, null ); | |
$r = wp_parse_args( $params, $defaults ); | |
if ( empty( $r['walker'] ) || ! ( $r['walker'] instanceof Walker ) ) { | |
$walker = new Customify_Walker_Category_Checklist; | |
} else { | |
$walker = $r['walker']; | |
} | |
$taxonomy = $r['taxonomy']; | |
$args = array( 'taxonomy' => $taxonomy ); | |
$tax = get_taxonomy( $taxonomy ); | |
if ( is_array( $r['selected_cats'] ) ) { | |
$args['selected_cats'] = $r['selected_cats']; | |
} else { | |
$args['selected_cats'] = array(); | |
} | |
$categories = (array) get_terms( $taxonomy, array( 'get' => 'all' ) ); | |
$output = ''; | |
// Then the rest of them | |
$output .= call_user_func_array( array( $walker, 'walk' ), array( $categories, 0, $args ) ); | |
if ( $r['echo'] ) { | |
echo $output; | |
} | |
return $output; | |
} | |
/** | |
* Output widget. | |
* | |
* @see WP_Widget | |
* | |
* @param array $args Arguments. | |
* @param array $instance Instance. | |
*/ | |
public function widget( $args, $instance ) { | |
if ( ! is_shop() && ! is_product_taxonomy() ) { | |
return; | |
} | |
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); | |
$query_type = isset( $instance['query_type'] ) ? $instance['query_type'] : $this->settings['query_type']['std']; | |
if( ! isset( $instance['data_type'] ) ) { | |
$instance['data_type'] = 'categories'; | |
} | |
switch ( $instance['data_type'] ) { | |
case 'product_cat': case 'product_tag': | |
$taxonomy = $instance['data_type']; | |
break; | |
default: | |
$taxonomy = $instance['data_type']; | |
} | |
if ( ! taxonomy_exists( $taxonomy ) ) { | |
$taxonomy = wc_attribute_taxonomy_name( $taxonomy ); | |
} | |
if ( ! taxonomy_exists( $taxonomy ) ) { | |
return; | |
} | |
$get_terms_args = array( 'hide_empty' => '1' ); | |
$orderby = wc_attribute_orderby( $taxonomy ); | |
switch ( $orderby ) { | |
case 'name': | |
$get_terms_args['orderby'] = 'name'; | |
$get_terms_args['menu_order'] = false; | |
break; | |
case 'id': | |
$get_terms_args['orderby'] = 'id'; | |
$get_terms_args['order'] = 'ASC'; | |
$get_terms_args['menu_order'] = false; | |
break; | |
case 'menu_order': | |
$get_terms_args['menu_order'] = 'ASC'; | |
break; | |
default: | |
$get_terms_args['orderby'] = 'name'; | |
$get_terms_args['menu_order'] = false; | |
} | |
$terms = get_terms( $taxonomy, $get_terms_args ); | |
if ( 0 === count( $terms ) ) { | |
return; | |
} | |
ob_start(); | |
$this->widget_start( $args, $instance ); | |
// List display. | |
echo '<form class="customify-wc-filter-form">'; | |
echo '<ul class="woocommerce-widget-layered-nav-list">'; | |
if ( ! function_exists('wp_terms_checklist') ) { | |
require_once ABSPATH.'/wp-admin/includes/template.php'; | |
} | |
$this->wp_terms_checklist( array( 'taxonomy' => $taxonomy, 'checked_ontop' => false, 'selected' => $_chosen_attributes ) ); | |
echo '</ul>'; | |
echo '<input type="hidden" name="query_type_'.esc_attr( str_replace( 'pa_', '', $taxonomy ) ).'" value="'.esc_attr( $query_type ).'">'; | |
echo '</form>'; | |
$this->widget_end( $args ); | |
echo ob_get_clean(); // @codingStandardsIgnoreLine | |
} | |
/** | |
* 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 ); | |
} | |
/** | |
* Count products within certain terms, taking the main WP query into consideration. | |
* | |
* This query allows counts to be generated based on the viewed products, not all products. | |
* | |
* @param array $term_ids Term IDs. | |
* @param string $taxonomy Taxonomy. | |
* @param string $query_type Query Type. | |
* @return array | |
*/ | |
protected function get_filtered_term_product_counts( $term_ids, $taxonomy, $query_type ) { | |
global $wpdb; | |
$tax_query = WC_Query::get_main_tax_query(); | |
$meta_query = WC_Query::get_main_meta_query(); | |
if ( 'or' === $query_type ) { | |
foreach ( $tax_query as $key => $query ) { | |
if ( is_array( $query ) && $taxonomy === $query['taxonomy'] ) { | |
unset( $tax_query[ $key ] ); | |
} | |
} | |
} | |
$meta_query = new WP_Meta_Query( $meta_query ); | |
$tax_query = new WP_Tax_Query( $tax_query ); | |
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); | |
$tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); | |
// Generate query. | |
$query = array(); | |
$query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id"; | |
$query['from'] = "FROM {$wpdb->posts}"; | |
$query['join'] = " | |
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id | |
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) | |
INNER JOIN {$wpdb->terms} AS terms USING( term_id ) | |
" . $tax_query_sql['join'] . $meta_query_sql['join']; | |
$query['where'] = " | |
WHERE {$wpdb->posts}.post_type IN ( 'product' ) | |
AND {$wpdb->posts}.post_status = 'publish'" | |
. $tax_query_sql['where'] . $meta_query_sql['where'] . | |
'AND terms.term_id IN (' . implode( ',', array_map( 'absint', $term_ids ) ) . ')'; | |
$search = WC_Query::get_main_search_query_sql(); | |
if ( $search ) { | |
$query['where'] .= ' AND ' . $search; | |
} | |
$query['group_by'] = 'GROUP BY terms.term_id'; | |
$query = apply_filters( 'woocommerce_get_filtered_term_product_counts_query', $query ); | |
$query = implode( ' ', $query ); | |
// We have a query - let's see if cached results of this query already exist. | |
$query_hash = md5( $query ); | |
// Maybe store a transient of the count values. | |
$cache = apply_filters( 'woocommerce_layered_nav_count_maybe_cache', true ); | |
if ( true === $cache ) { | |
$cached_counts = (array) get_transient( 'wc_layered_nav_counts_' . $taxonomy ); | |
} else { | |
$cached_counts = array(); | |
} | |
if ( ! isset( $cached_counts[ $query_hash ] ) ) { | |
$results = $wpdb->get_results( $query, ARRAY_A ); // @codingStandardsIgnoreLine | |
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) ); | |
$cached_counts[ $query_hash ] = $counts; | |
if ( true === $cache ) { | |
set_transient( 'wc_layered_nav_counts_' . $taxonomy, $cached_counts, DAY_IN_SECONDS ); | |
} | |
} | |
return array_map( 'absint', (array) $cached_counts[ $query_hash ] ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment