簡體   English   中英

在 WooCommerce 管理快速訂單預覽中自定義內容

[英]Customize content in WooCommerce admin quick order preview

我是 WordPress 的新手,我在我的項目中使用 WooCommerce 插件,我需要修改 WooCommerce 的一些模板文件和一些核心文件。

我已經創建了子主題並在我的子主題中創建了woocommerce文件夾,因此我可以在那里創建/修改模板文件,這些文件在 WooCommerce 插件更新期間不會丟失。 但正如我在一些文章中看到的,不建議修改 WooCommerce 的核心文件。

我在 WooCommerce 插件中自定義了這個核心文件includes\\admin\\meta-boxes\\views\\html-order-item ,我有點擔心未來的插件更新(我的自定義更改是否會保留)。 我試圖在woocommerce文件夾內的我的子主題中復制這個文件,但它似乎沒有覆蓋原始文件,所以它沒有效果。

在這個“html-order-item.php”文件中,我剛剛添加了一小段代碼,其中有一個下載按鈕來下載產品的原始圖像。

如何使用“干凈的推薦方式(使用鈎子/過濾器或模板)”來實現這一點?
請提出任何實現它的方法。

這是我的代碼片段(我的自定義以/* Custom code added by Amol */開頭):

<?php
/**
 * Shows an order item
 *
 * @var object $item The item being displayed
 * @var int $item_id The id of the item being displayed
 */
  if (!defined('ABSPATH')) {
  exit;
 }
$product_link = $_product ? admin_url('post.php?post=' . absint($_product->id) . '&action=edit') : '';
$thumbnail = $_product ? apply_filters('woocommerce_admin_order_item_thumbnail', $_product->get_image('thumbnail', array('title' => ''), false), $item_id, $item) : '';
$tax_data = empty($legacy_order) && wc_tax_enabled() ? maybe_unserialize(isset($item['line_tax_data']) ? $item['line_tax_data'] : '' ) : false;
$item_total = ( isset($item['line_total']) ) ? esc_attr(wc_format_localized_price($item['line_total'])) : '';
$item_subtotal = ( isset($item['line_subtotal']) ) ? esc_attr(wc_format_localized_price($item['line_subtotal'])) : '';

<tr class="item <?php echo apply_filters('woocommerce_admin_html_order_item_class', (!empty($class) ? $class : ''), $item, $order); ?>" data-order_item_id="<?php echo $item_id; ?>">
 <td class="thumb">
    <?php
    echo '<div class="wc-order-item-thumbnail">' . wp_kses_post($thumbnail) . '</div>';
    ?>
</td>
 <td class="name" data-sort-value="<?php echo esc_attr($item['name']); ?>">
    <?php
    echo $product_link ? '<a href="' . esc_url($product_link) . '" class="wc-order-item-name">' . esc_html($item['name']) . '</a>' : '<div class="class="wc-order-item-name"">' . esc_html($item['name']) . '</div>';   

    if ($_product && $_product->get_sku()) {
        echo '<div class="wc-order-item-sku"><strong>' . __('SKU:', 'woocommerce') . '</strong> ' . esc_html($_product->get_sku()) . '</div>';
    }

    if (!empty($item['variation_id'])) {
        echo '<div class="wc-order-item-variation"><strong>' . __('Variation ID:', 'woocommerce') . '</strong> ';
        if (!empty($item['variation_id']) && 'product_variation' === get_post_type($item['variation_id'])) {
            echo esc_html($item['variation_id']);
        } elseif (!empty($item['variation_id'])) {
            echo esc_html($item['variation_id']) . ' (' . __('No longer exists', 'woocommerce') . ')';
        }
        echo '</div>';
    }
    ?>
    <input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr($item_id); ?>" />
    <input type="hidden" name="order_item_tax_class[<?php echo absint($item_id); ?>]" value="<?php echo isset($item['tax_class']) ? esc_attr($item['tax_class']) : ''; ?>" />

    <?php do_action('woocommerce_before_order_itemmeta', $item_id, $item, $_product) ?>
    <?php include( 'html-order-item-meta.php' ); ?>
    <?php do_action('woocommerce_after_order_itemmeta', $item_id, $item, $_product) ?>

    <?php echo $_product->get_categories(', ', '<div class="wc-order-item-variation"><strong>' . _n('Category:', 'woocommerce:', sizeof(get_the_terms($item['product_id'], 'product_cat')), 'woocommerce') . ' ', '</strong></div>'); ?> 
    <div  style="float: left;" >
        <?php
        $image_link = wp_get_attachment_image_src(get_post_thumbnail_id($_product->id), 'large');

        echo isset($image_link[0]) ? '<img src = "' . $image_link[0] . '" width = "200">' : '';
        ?>
    </div>
    <?php
    /* Custom code added by Amol */
    $post = $_product->post;
    $attachment_count = count($_product->get_gallery_attachment_ids());
    $gallery = $attachment_count > 0 ? '[product-gallery]' : '';
    $props = wc_get_product_attachment_props(get_post_thumbnail_id(), $post);
    $image = get_the_post_thumbnail($post->ID, apply_filters('single_product_large_thumbnail_size', 'shop_single'), array(
        'title' => $props['title'],
        'alt' => $props['alt'],
    ));
    echo apply_filters(
            'woocommerce_single_product_image_html', sprintf(
                    '<a style="text-decoration: none;clear:both;float: left;margin-top: 5px;" href="%s" download = "Order#' . $order->id . '-' . $item['variation_id'] . '"><input type = "button" value="Download image"/></a>', esc_url($props['url'])
            ), $post->ID
    );
    //End of custom code by Amol
    ?>
</td>

<?php do_action('woocommerce_admin_order_item_values', $_product, $item, absint($item_id)); ?>

<td class="item_cost" width="1%" data-sort-value="<?php echo esc_attr($order->get_item_subtotal($item, false, true)); ?>">
    <div class="view">
        <?php
        if (isset($item['line_total'])) {
            echo wc_price($order->get_item_total($item, false, true), array('currency' => $order->get_order_currency()));

            if (isset($item['line_subtotal']) && $item['line_subtotal'] != $item['line_total']) {
                echo '<span class="wc-order-item-discount">-' . wc_price(wc_format_decimal($order->get_item_subtotal($item, false, false) - $order->get_item_total($item, false, false), ''), array('currency' => $order->get_order_currency())) . '</span>';
            }
        }
        ?>
    </div>
</td>
<td class="quantity" width="1%">
    <div class="view">
        <?php
        echo '<small class="times">&times;</small> ' . ( isset($item['qty']) ? esc_html($item['qty']) : '1' );

        if ($refunded_qty = $order->get_qty_refunded_for_item($item_id)) {
            echo '<small class="refunded">' . ( $refunded_qty * -1 ) . '</small>';
        }
        ?>
    </div>
    <div class="edit" style="display: none;">
        <?php $item_qty = esc_attr($item['qty']); ?>
        <input type="number" step="<?php echo apply_filters('woocommerce_quantity_input_step', '1', $_product); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint($item_id); ?>]" placeholder="0" value="<?php echo $item_qty; ?>" data-qty="<?php echo $item_qty; ?>" size="4" class="quantity" />
    </div>
    <div class="refund" style="display: none;">
        <input type="number" step="<?php echo apply_filters('woocommerce_quantity_input_step', '1', $_product); ?>" min="0" max="<?php echo $item['qty']; ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint($item_id); ?>]" placeholder="0" size="4" class="refund_order_item_qty" />
    </div>
</td>
<td class="line_cost" width="1%" data-sort-value="<?php echo esc_attr(isset($item['line_total']) ? $item['line_total'] : '' ); ?>">
    <div class="view">
        <?php
        if (isset($item['line_total'])) {
            echo wc_price($item['line_total'], array('currency' => $order->get_order_currency()));
        }

        if (isset($item['line_subtotal']) && $item['line_subtotal'] !== $item['line_total']) {
            echo '<span class="wc-order-item-discount">-' . wc_price(wc_format_decimal($item['line_subtotal'] - $item['line_total'], ''), array('currency' => $order->get_order_currency())) . '</span>';
        }

        if ($refunded = $order->get_total_refunded_for_item($item_id)) {
            echo '<small class="refunded">' . wc_price($refunded, array('currency' => $order->get_order_currency())) . '</small>';
        }
        ?>
    </div>
    <div class="edit" style="display: none;">
        <div class="split-input">
            <div class="input">
                <label><?php esc_attr_e('Pre-discount:', 'woocommerce'); ?></label>
                <input type="text" name="line_subtotal[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo $item_subtotal; ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo $item_subtotal; ?>" />
            </div>
            <div class="input">
                <label><?php esc_attr_e('Total:', 'woocommerce'); ?></label>
                <input type="text" name="line_total[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo $item_total; ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e('After pre-tax discounts.', 'woocommerce'); ?>" data-total="<?php echo $item_total; ?>" />
            </div>
        </div>
    </div>
    <div class="refund" style="display: none;">
        <input type="text" name="refund_line_total[<?php echo absint($item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" class="refund_line_total wc_input_price" />
    </div>
</td>

<?php
    if (!empty($tax_data)) {
        foreach ($order_taxes as $tax_item) {
            $tax_item_id = $tax_item['rate_id'];
            $tax_item_total = isset($tax_data['total'][$tax_item_id]) ? $tax_data['total'][$tax_item_id] : '';
            $tax_item_subtotal = isset($tax_data['subtotal'][$tax_item_id]) ? $tax_data['subtotal'][$tax_item_id] : '';
            ?>
            <td class="line_tax" width="1%">
                <div class="view">
                    <?php
                    if ('' != $tax_item_total) {
                        echo wc_price(wc_round_tax_total($tax_item_total), array('currency' => $order->get_order_currency()));
                    } else {
                        echo '&ndash;';
                    }

                    if (isset($item['line_subtotal']) && $item['line_subtotal'] !== $item['line_total']) {
                        echo '<span class="wc-order-item-discount">-' . wc_price(wc_round_tax_total($tax_item_subtotal - $tax_item_total), array('currency' => $order->get_order_currency())) . '</span>';
                    }

                    if ($refunded = $order->get_tax_refunded_for_item($item_id, $tax_item_id)) {
                        echo '<small class="refunded">' . wc_price($refunded, array('currency' => $order->get_order_currency())) . '</small>';
                    }
                    ?>
                </div>
                <div class="edit" style="display: none;">
                    <div class="split-input">
                        <div class="input">
                            <label><?php esc_attr_e('Pre-discount:', 'woocommerce'); ?></label>
                            <input type="text" name="line_subtotal_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo esc_attr(wc_format_localized_price($tax_item_subtotal)); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr(wc_format_localized_price($tax_item_subtotal)); ?>" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
                        </div>
                        <div class="input">
                            <label><?php esc_attr_e('Total:', 'woocommerce'); ?></label>
                            <input type="text" name="line_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" value="<?php echo esc_attr(wc_format_localized_price($tax_item_total)); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr(wc_format_localized_price($tax_item_total)); ?>" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
                        </div>
                    </div>
                </div>
                <div class="refund" style="display: none;">
                    <input type="text" name="refund_line_tax[<?php echo absint($item_id); ?>][<?php echo esc_attr($tax_item_id); ?>]" placeholder="<?php echo wc_format_localized_price(0); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr($tax_item_id); ?>" />
                </div>
            </td>
            <?php
        }
    }
    ?>

    <td class="wc-order-edit-line-item" width="1%">
        <div class="wc-order-edit-line-item-actions">
            <?php if ($order->is_editable()) : ?>
                <a class="edit-order-item tips" href="#" data-tip="<?php esc_attr_e('Edit item', 'woocommerce'); ?>"></a><a class="delete-order-item tips" href="#" data-tip="<?php esc_attr_e('Delete item', 'woocommerce'); ?>"></a>
                <?php endif; ?>
        </div>
    </td>
</tr>

提前致謝。

— 代碼更新 2 — (發現問題,請參閱代碼中的注釋)

就在html-order-item.php核心文件中的自定義代碼下,如果您查看現有代碼,您將擁有可用於代碼的woocommerce_admin_order_item_values鈎子,而不是覆蓋 WooCommerce 核心文件。

但是您還需要使用woocommerce_admin_order_item_headers正如您將在下面的代碼片段中看到的那樣......

因為是的,當 WooCommerce 更新時,您將失去該 PHP 文件中的代碼自定義 這就是為什么您會在 WordPress 和 WooCommerce 核心文件任何地方找到許多不同的鈎子,用於自定義。

您不能將此核心文件復制到您的活動子主題(或活動主題),並且這樣做不會對其產生任何影響。

您可以做的是將 WooCommerce 插件中的templates文件夾復制到您的活動子主題(或活動主題)並將其重命名為woocommerce 這樣您就可以通過您的主題覆蓋 WooCommerce 模板, 如本文檔中所述

現在,首先您要替換插件中的原始核心文件。

在您的子主題中,您通常有一個 function.php 文件,您將在其中添加以下代碼(一個掛鈎函數):

add_action( 'woocommerce_admin_order_item_headers', 'download_image_admin_order_item_headers', 10, 0 );
function download_image_admin_order_item_headers(){
    echo '<th class="item sortable" colspan="1" data-sort="string-ins">' . __( 'Downloads', 'woocommerce' ) .'</th>';
}

add_action( 'woocommerce_admin_order_item_values', 'download_image_order_item_values', 10, 3 );
function download_image_order_item_values( $_product, $item, $item_id ){
    // Calling global $post to get the order ID
    global $post;
    // The Order ID
    $order_id = $post->ID;

    // the Product ID and variation ID (if different of zero for variations)
    $product_id = $item['product_id'];
    $variation_id = $item['variation_id'];
    
    // If is not a variable product we replace the variation ID by the product ID
    if (empty($variation_id)) $variation_id = $product_id;

    // HERE ==> Getting an instance of product object, Avoiding an error:
    // "Fatal error: Call to a member function get_gallery_attachment_ids()"
    $product = new WC_Product($product_id);
    // the Product post object
    $post_product = $product->post;

    $attachment_count = count($product->get_gallery_attachment_ids());
    $gallery = $attachment_count > 0 ? '[product-gallery]' : '';

    // CODE ERROR ===> This was returning empty before. You need to put
    // the product ID in get_post_thumbnail_id() function to get something
    $props = wc_get_product_attachment_props(get_post_thumbnail_id($product_id), $post_product);

    // Testing $props output (array not empty) => comment/uncomment line below
    // echo '<br>ITEM ID: ' . $item_id . '<br><pre>'; var_dump($props);  echo '</pre><br>';

    $image = get_the_post_thumbnail( $product->id, apply_filters('single_product_large_thumbnail_size', 'shop_single' ), array(
        'title' => $props['title'],
        'alt' => $props['alt'],
    ));



    // Added a condition to avoid other line items than products (like shipping line)
    if(!empty($product_id))
        echo apply_filters(
                'woocommerce_single_product_image_html', sprintf(
                        '<td class="name" colspan="1" ><a style="text-decoration: none;clear:both;float: left;margin-top: 5px;" href="%s" download = "Order#' . $order_id . '-' . $variation_id . '"><input type = "button" value="Download image"/></a></td>', esc_url($props['url'])
                ), $product->id
        );

 }

在項目元框上的管理訂單編輯頁面中,您將看到:

在此處輸入圖片說明

代碼位於活動子主題(活動主題或任何插件文件)的 function.php 文件中。

此代碼經過測試並有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM