全部商品管理篩選頁面

再全部商品的管理頁面,可以用標籤篩選商品。

 
<?php
/**
 * Plugin Name: WC Admin Filter Manager
 * Description: 在後台「商品 → 所有商品」頁提供管理介面:可勾選移除(商品類型/存貨狀態/品牌/商品分類)等既有篩選;並可新增「商品標籤」篩選。
 * Version:     1.2.0
 * Author:      (Your Name)
 * License:     GPL-2.0+
 * Text Domain: wc-admin-filter-manager
 */
 
if ( ! defined( 'ABSPATH' ) ) exit;
 
class WC_Admin_Filter_Manager {
    const OPT_KEY = 'wca_filter_manager';
    public function __construct() {
        // 設定頁
        add_action( 'admin_menu', [ $this, 'add_settings_page' ] );
        add_action( 'admin_init', [ $this, 'register_settings' ] );
 
        // 實際作用於商品清單
        add_filter( 'woocommerce_products_admin_list_table_filters', [ $this, 'maybe_remove_core_filters' ], 20 );
        add_filter( 'woocommerce_product_filters', [ $this, 'maybe_strip_taxonomy_dropdowns' ], 20 );
        add_action( 'restrict_manage_posts', [ $this, 'maybe_add_product_tag_dropdown' ], 20 );
        add_filter( 'parse_query', [ $this, 'apply_product_tag_filter' ] );
    }
 
    /** === 設定頁 === */
    public function add_settings_page() {
        add_submenu_page(
            'woocommerce',
            __( '後台商品篩選管理', 'wc-admin-filter-manager' ),
            __( '篩選管理', 'wc-admin-filter-manager' ),
            'manage_woocommerce',
            'wc-admin-filter-manager',
            [ $this, 'render_settings_page' ]
        );
    }
 
    public function register_settings() {
        register_setting( 'wca_fm_group', self::OPT_KEY );
        add_settings_section( 'wca_fm_section_main', '', '__return_false', 'wc-admin-filter-manager' );
 
        add_settings_field(
            'remove_filters',
            __( '要移除的篩選(後台「所有商品」頁)', 'wc-admin-filter-manager' ),
            [ $this, 'field_remove_filters' ],
            'wc-admin-filter-manager',
            'wca_fm_section_main'
        );
 
        add_settings_field(
            'add_filters',
            __( '要新增的篩選', 'wc-admin-filter-manager' ),
            [ $this, 'field_add_filters' ],
            'wc-admin-filter-manager',
            'wca_fm_section_main'
        );
    }
 
    public function get_options() {
        $defaults = [
            'remove_product_type' => 0,
            'remove_stock_status' => 0,
            'remove_brand'        => 0,
            'remove_category'     => 0,
            'add_product_tag'     => 1, // 預設啟用商品標籤篩選
        ];
        $saved = get_option( self::OPT_KEY, [] );
        return wp_parse_args( is_array( $saved ) ? $saved : [], $defaults );
    }
 
    public function render_settings_page() {
        if ( ! current_user_can( 'manage_woocommerce' ) ) {
            return;
        }
        ?>
        <div class="wrap">
            <h1><?php esc_html_e( '後台商品篩選管理', 'wc-admin-filter-manager' ); ?></h1>
            <form method="post" action="options.php">
                <?php
                settings_fields( 'wca_fm_group' );
                do_settings_sections( 'wc-admin-filter-manager' );
                submit_button();
                ?>
            </form>
            <p style="opacity:.8">
                <?php esc_html_e('提示:品牌篩選需搭配品牌 taxonomy(例如 WooCommerce Brands 外掛的 product_brand)。若沒有該 taxonomy,本選項不會有作用。', 'wc-admin-filter-manager'); ?>
            </p>
        </div>
        <?php
    }
 
    public function field_remove_filters() {
        $o = $this->get_options();
        ?>
        <label><input type="checkbox" name="<?php echo esc_attr(self::OPT_KEY); ?>[remove_product_type]" value="1" <?php checked( $o['remove_product_type'], 1 ); ?> /> <?php esc_html_e('商品類型', 'wc-admin-filter-manager'); ?></label><br/>
        <label><input type="checkbox" name="<?php echo esc_attr(self::OPT_KEY); ?>[remove_stock_status]" value="1" <?php checked( $o['remove_stock_status'], 1 ); ?> /> <?php esc_html_e('存貨狀態', 'wc-admin-filter-manager'); ?></label><br/>
        <label><input type="checkbox" name="<?php echo esc_attr(self::OPT_KEY); ?>[remove_brand]" value="1" <?php checked( $o['remove_brand'], 1 ); ?> /> <?php esc_html_e('品牌篩選', 'wc-admin-filter-manager'); ?></label><br/>
        <label><input type="checkbox" name="<?php echo esc_attr(self::OPT_KEY); ?>[remove_category]" value="1" <?php checked( $o['remove_category'], 1 ); ?> /> <?php esc_html_e('商品分類', 'wc-admin-filter-manager'); ?></label>
        <?php
    }
 
    public function field_add_filters() {
        $o = $this->get_options();
        ?>
        <label><input type="checkbox" name="<?php echo esc_attr(self::OPT_KEY); ?>[add_product_tag]" value="1" <?php checked( $o['add_product_tag'], 1 ); ?> /> <?php esc_html_e('商品標籤', 'wc-admin-filter-manager'); ?></label>
        <?php
    }
 
    /** === 作用:移除核心篩選 === */
    public function maybe_remove_core_filters( $filters ) {
        $o = $this->get_options();
 
        if ( ! empty( $o['remove_product_type'] ) && isset( $filters['product_type'] ) ) {
            unset( $filters['product_type'] );
        }
        if ( ! empty( $o['remove_stock_status'] ) && isset( $filters['stock_status'] ) ) {
            unset( $filters['stock_status'] );
        }
 
        // 有些環境下,分類/品牌也可能出現在此陣列,盡量處理
        if ( ! empty( $o['remove_category'] ) ) {
            foreach ( [ 'product_category', 'product_cat' ] as $k ) {
                if ( isset( $filters[ $k ] ) ) unset( $filters[ $k ] );
            }
        }
        if ( ! empty( $o['remove_brand'] ) ) {
            foreach ( [ 'product_brand', 'brand' ] as $k ) {
                if ( isset( $filters[ $k ] ) ) unset( $filters[ $k ] );
            }
        }
 
        return $filters;
    }
 
    /** === 作用:剔除 taxonomy 下拉(分類/品牌) ===
     * WooCommerce 會透過 woocommerce_product_filters 印出 HTML 字串(包含商品分類、視需求也可能包含品牌)。
     * 這裡用簡單的字串/正則把不需要的下拉移除。
     */
    public function maybe_strip_taxonomy_dropdowns( $output ) {
        $o = $this->get_options();
        $orig = $output;
 
        // 移除「商品分類」:name="product_cat" 或 id="dropdown_product_cat"
        if ( ! empty( $o['remove_category'] ) ) {
            $output = preg_replace( '#<select[^>]*(name=["\']product_cat["\']|id=["\']dropdown_product_cat["\'])[^>]*>.*?</select>#si', '', $output );
        }
 
        // 移除「品牌」(WooCommerce Brands 預設 name="product_brand")
        if ( ! empty( $o['remove_brand'] ) ) {
            $output = preg_replace( '#<select[^>]*name=["\']product_brand["\'][^>]*>.*?</select>#si', '', $output );
        }
 
        return $output;
    }
 
    /** === 作用:新增「商品標籤」篩選 === */
    public function maybe_add_product_tag_dropdown( $post_type ) {
        $o = $this->get_options();
        if ( empty( $o['add_product_tag'] ) ) return;
        if ( $post_type !== 'product' ) return;
 
        $taxonomy = 'product_tag';
        $tax_obj  = get_taxonomy( $taxonomy );
        if ( ! $tax_obj ) return;
 
        $selected = isset( $_GET[ $taxonomy ] ) ? sanitize_text_field( wp_unslash( $_GET[ $taxonomy ] ) ) : '';
 
        wp_dropdown_categories( [
            'show_option_all' => sprintf( esc_html__( '所有 %s', 'wc-admin-filter-manager' ), $tax_obj->labels->name ),
            'taxonomy'        => $taxonomy,
            'name'            => $taxonomy,
            'orderby'         => 'name',
            'selected'        => $selected,
            'hierarchical'    => false,
            'show_count'      => true,
            'hide_empty'      => false,
            'value_field'     => 'term_id',
        ] );
    }
 
    public function apply_product_tag_filter( $query ) {
        if ( ! is_admin() || ! $query->is_main_query() ) return $query;
 
        global $pagenow;
        if ( $pagenow !== 'edit.php' ) return $query;
        if ( ( isset( $_GET['post_type'] ) ? sanitize_key( $_GET['post_type'] ) : 'post' ) !== 'product' ) return $query;
 
        $taxonomy = 'product_tag';
        if ( ! empty( $_GET[ $taxonomy ] ) && is_numeric( $_GET[ $taxonomy ] ) ) {
            $term = get_term_by( 'id', (int) $_GET[ $taxonomy ], $taxonomy );
            if ( $term && ! is_wp_error( $term ) ) {
                $query->query_vars[ $taxonomy ] = $term->slug;
            }
        }
        return $query;
    }
}
 
new WC_Admin_Filter_Manager();

wc-admin-tag-filter

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料