如何添加自定义 woocommerce 管理字段类型

How to add custom woocommerce admin field type

我已经将一种自定义字段类型添加到 woocommerce 管理字段中,并且工作了 100%。

但此代码在 woocommerce 插件中 (woocommerce/includes/admin/class-wc-admin-settings.php)。

我现在的问题是如何将我的自定义 woocommerce 管理字段类型从 woocoommerce 插件排除、挂钩或过滤到我的插件。因此,我的自定义字段类型在更新 woocommerce 时仍然存在并且有效。

这是class-wc-admin-settings.php定制的

<?php
...
class WC_Admin_Settings {
...

public static function output_fields( $options ) {
...
switch ( $value['type'] ) {
    case 'productcategory' :

    $option_value = (array) self::get_option( $value['id'] );

    ?><tr valign="top">
        <th scope="row" class="titledesc">
            <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
            <?php echo $tooltip_html; ?>
        </th>
        <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
            <fieldset>

                <ul class="" style="margin:0; padding:0;">
                <?php
                    $args = array(
                        'orderby' => 'name',
                        'hide_empty'=> 0,
                        'taxonomy' => 'product_cat' 
                    );

                    $all_categories = get_categories( $args );
                    $index = 0;
                    $count = count($all_categories);
                    $numItemsPerRow = ceil($count / 2);
                    $numItemsOffsetFix = $count % 2 == 1;

                    echo '<div class="columns" style="width:auto; display:inline-block; height:auto; float:left; padding:0; margin:0 25px 0 0;">';

                    foreach ($all_categories as $key => $val) {
                        if ($index > 0 and $index % $numItemsPerRow == 0) {
                            echo '</div><div class="columns">';
                            if ($numItemsOffsetFix) {
                                $numItemsPerRow--;
                                $numItemsOffsetFix = false;
                            }
                        }
                    //foreach ( $value['options'] as $key => $val ) {
                        ?>
                        <li style="">
                            <label><input type="checkbox" 
                                name="<?php echo esc_attr( $value['id'] ); ?>[]"
                                id="<?php echo esc_attr( $val->term_id )?>"
                                value="<?php echo esc_attr( $val->term_id )?>" 
                                <?php
                                    if ( in_array( $val->term_id,$option_value ) ) {
                                        echo ' checked="checked"';
                                    }
                                ?>
                                /> <?php echo $val->name; ?>
                            </label>
                        </li>
                        <?php
                        $index++;
                    }
                ?>
                </ul>
            </fieldset>
            <fieldset>
                <?php echo $description; ?>
            </fieldset>
        </td>
    </tr><?php
 break;
...
} //end switch

...
} //end output_fields function

public static function save_fields( $options ) {
...
    switch ( $option['type'] ) {
    ...
        case 'productcategory':
        $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) );
        break;
    ...
    }
...
} //end save_fields function

...
} //end class
?>

谢谢指教。

有个do_action as the default case in the switch statement. Meaning, that if nothing has matched yet in the core code it will see if anything is attached to the action hook. Similarly, you can sanitize via the woocommerce_admin_settings_sanitize_option_$option_name filter

因此,这是我最好的猜测:

// handle output of new settings type
add_action( 'woocommerce_admin_field_productcategory', 'output_productcategory_fields' );
function output_productcategory_fields( $value ) {

    $option_value = (array) WC_Admin_Settings::get_option( $value['id'] );

    ?><tr valign="top">
        <th scope="row" class="titledesc">
            <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
            <?php echo $tooltip_html; ?>
        </th>
        <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
            <fieldset>

                <ul class="" style="margin:0; padding:0;">
                <?php
                    $args = array(
                        'orderby' => 'name',
                        'hide_empty'=> 0,
                        'taxonomy' => 'product_cat' 
                    );

                    $all_categories = get_categories( $args );
                    $index = 0;
                    $count = count($all_categories);
                    $numItemsPerRow = ceil($count / 2);
                    $numItemsOffsetFix = $count % 2 == 1;

                    echo '<div class="columns" style="width:auto; display:inline-block; height:auto; float:left; padding:0; margin:0 25px 0 0;">';

                    foreach ($all_categories as $key => $val) {
                        if ($index > 0 and $index % $numItemsPerRow == 0) {
                            echo '</div><div class="columns">';
                            if ($numItemsOffsetFix) {
                                $numItemsPerRow--;
                                $numItemsOffsetFix = false;
                            }
                        }
                    //foreach ( $value['options'] as $key => $val ) {
                        ?>
                        <li style="">
                            <label><input type="checkbox" 
                                name="<?php echo esc_attr( $value['id'] ); ?>[]"
                                id="<?php echo esc_attr( $val->term_id )?>"
                                value="<?php echo esc_attr( $val->term_id )?>" 
                                <?php
                                    if ( in_array( $val->term_id,$option_value ) ) {
                                        echo ' checked="checked"';
                                    }
                                ?>
                                /> <?php echo $val->name; ?>
                            </label>
                        </li>
                        <?php
                        $index++;
                    }
                ?>
                </ul>
            </fieldset>
            <fieldset>
                <?php echo $description; ?>
            </fieldset>
        </td>
    </tr><?php

}

// sanitize data for new settings type
add_filter( 'woocommerce_admin_settings_sanitize_option_productcategory', 'sanitize_productcategory_option', 10, 3 );
function sanitize_productcategory_option( $value, $option, $raw_value ){
    $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) );
    return $value;
}