Woocommerce产品数量过滤器滑块 - 小工具

时间:2017-07-20 09:16:29

标签: php jquery wordpress woocommerce widget

我正在尝试将一个小部件添加到Woocommerce以使用滑块按数量过滤产品。我通过更改价格过滤器滑块的woocommerce的开源代码来实现这一目标。它一旦在网站上打印就没有错误,但它不会过滤结果。 URL上的输出也是预期的。滑块不起作用,但如果我无法修复它就没问题了。截至目前,它有两个输入字段:最大和最小库存数量。请帮忙。我相信其他人也会从中受益。我需要它,因为该网站是批发的,如果产品不可用是客户想要的最小数量,他们可以过滤掉。

   // Register and load the widget
function my_stock_widget() {
    register_widget( 'WC_Widget_Stock_Filter' );
}
add_action( 'widgets_init', 'my_stock_widget' );

class WC_Widget_Stock_Filter extends WC_Widget {
    /**
     * Constructor.
     */
    public function __construct() {
        $this->widget_cssclass    = 'woocommerce widget_stock_filter';
        $this->widget_description = __( 'Shows a stock filter slider in a widget which lets you narrow down the list of shown products when viewing product categories.', 'woocommerce' );
        $this->widget_id          = 'woocommerce_stock_filter';
        $this->widget_name        = __( 'WooCommerce stock filter', 'woocommerce' );
        $this->settings           = array(
            'title'  => array(
                'type'  => 'text',
                'std'   => __( 'Filter by stock', 'woocommerce' ),
                'label' => __( 'Title', 'woocommerce' ),
            ),
        );
        $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
        wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2' );
        wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), WC_VERSION, true );
        wp_register_script( 'wc-stock-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch', 'accounting' ), WC_VERSION, true );
        wp_localize_script( 'wc-stock-slider', 'woocommerce_stock_slider_params', array(
            'min_stock'                    => isset( $_GET['min_stock'] ) ? esc_attr( $_GET['min_stock'] ) : '',
            'max_stock'                    => isset( $_GET['max_stock'] ) ? esc_attr( $_GET['max_stock'] ) : '',
            'currency_format_num_decimals' => 0,
//          'currency_format_symbol'       => get_woocommerce_currency_symbol(),
            'currency_format_decimal_sep'  => esc_attr( wc_get_price_decimal_separator() ),
            'currency_format_thousand_sep' => esc_attr( wc_get_price_thousand_separator() ),
//          'currency_format'              => esc_attr( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), get_woocommerce_stock_format() ) ),
        ) );
        parent::__construct();
    }
    /**
     * Output widget.
     *
     * @see WP_Widget
     *
     * @param array $args
     * @param array $instance
     */
    public function widget( $args, $instance ) {
        global $wp, $wp_the_query;
        if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
            return;
        }
        if ( ! $wp_the_query->post_count ) {
            return;
        }
        $min_stock = isset( $_GET['min_stock'] ) ? esc_attr( $_GET['min_stock'] ) : '';
        $max_stock = isset( $_GET['max_stock'] ) ? esc_attr( $_GET['max_stock'] ) : '';
        wp_enqueue_script( 'wc-stock-slider' );
        // Find min and max stock in current result set
        $stocks = $this->get_filtered_stock();
        $min    = floor( $stocks->min_stock );
        $max    = ceil( $stocks->max_stock );
        if ( $min === $max ) {
            return;
        }
        $this->widget_start( $args, $instance );
        if ( '' === get_option( 'permalink_structure' ) ) {
            $form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) );
        } else {
            $form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
        }
        /**
         * Adjust max if the store taxes are not displayed how they are stored.
         * Min is left alone because the product may not be taxable.
         * Kicks in when stocks excluding tax are displayed including tax.
         *
        if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_stocks_include_tax() ) {
            $tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
            $class_max   = $max;
            foreach ( $tax_classes as $tax_class ) {
                if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) {
                    $class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
                }
            }
            $max = $class_max;
        }*/
        echo '<form method="get" action="' . esc_url( $form_action ) . '">
            <div class="stock_slider_wrapper">
                <div class="stock_slider" style="display:none;"></div>
                <div class="stock_slider_amount">
                    <input type="text" id="min_stock" name="min_stock" value="' . esc_attr( $min_stock ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_stock_filter_widget_min_amount', $min ) ) . '" placeholder="' . esc_attr__( 'Min stock', 'woocommerce' ) . '" />
                    <input type="text" id="max_stock" name="max_stock" value="' . esc_attr( $max_stock ) . '" data-max="' . esc_attr( apply_filters( 'woocommerce_stock_filter_widget_max_amount', $max ) ) . '" placeholder="' . esc_attr__( 'Max stock', 'woocommerce' ) . '" />
                    <button type="submit" class="button">' . esc_html__( 'Filter', 'woocommerce' ) . '</button>
                    <div class="stock_label" style="display:none;">
                        ' . esc_html__( 'Stock:', 'woocommerce' ) . ' <span class="from"></span> &mdash; <span class="to"></span>
                    </div>
                    ' . wc_query_string_form_fields( null, array( 'min_stock', 'max_stock' ), '', true ) . '
                    <div class="clear"></div>
                </div>
            </div>
        </form>';
        $this->widget_end( $args );
    }
    /**
     * Get filtered min stock for current products.
     * @return int
     */
    protected function get_filtered_stock() {
        global $wpdb, $wp_the_query;
        $args       = $wp_the_query->query_vars;
        $tax_query  = isset( $args['tax_query'] ) ? $args['tax_query'] : array();
        $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array();
        if ( ! is_post_type_archive( 'product' ) && ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) {
            $tax_query[] = array(
                'taxonomy' => $args['taxonomy'],
                'terms'    => array( $args['term'] ),
                'field'    => 'slug',
            );
        }
        foreach ( $meta_query + $tax_query as $key => $query ) {
            if ( ! empty( $query['stock_filter'] ) || ! empty( $query['rating_filter'] ) ) {
                unset( $meta_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' );
        $sql  = "SELECT min( FLOOR( stock_meta.meta_value ) ) as min_stock, max( CEILING( stock_meta.meta_value ) ) as max_stock FROM {$wpdb->posts} ";
        $sql .= " LEFT JOIN {$wpdb->postmeta} as stock_meta ON {$wpdb->posts}.ID = stock_meta.post_id " . $tax_query_sql['join'] . $meta_query_sql['join'];
        $sql .= "   WHERE {$wpdb->posts}.post_type IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_stock_filter_meta_keys', array( 'product' ) ) ) ) . "')
                    AND {$wpdb->posts}.post_status = 'publish'
                    AND stock_meta.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_stock_filter_meta_keys', array( '_stock' ) ) ) ) . "')
                    AND stock_meta.meta_value > '' ";
        $sql .= $tax_query_sql['where'] . $meta_query_sql['where'];
        if ( $search = WC_Query::get_main_search_query_sql() ) {
            $sql .= ' AND ' . $search;
        }
        return $wpdb->get_row( $sql );
    }

0 个答案:

没有答案