自定义WooCommerce管理员快速订单预览中的内容 [英] Customize content in WooCommerce admin quick order preview

查看:70
本文介绍了自定义WooCommerce管理员快速订单预览中的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to WordPress and I am using WooCommerce plugin in my project where I need to modify some of template files and some of core files of WooCommerce.

我已经创建了子主题,并在子主题内创建了 woocommerce 文件夹,因此我可以在那里创建/修改模板文件,在WooCommerce插件更新期间不会丢失自定义设置.但是,正如我读过的一些文章一样,不建议修改WooCommerce的核心文件.

I have created child theme and created woocommerce folder inside my child theme and hence I can create/modify template files there which customizations won't be lost during WooCommerce plugin updates. But as I have read on some articles, modifying core files of WooCommerce is not recommended.

我已经在WooCommerce插件中自定义了此核心文件 includes\admin\meta-boxes\views\html-order-item ,并且我对将来的插件更新有些担心(我的自定义更改是否会保留).我试图将此文件复制到 woocommerce 文件夹中的子主题中,但是它似乎没有覆盖原始文件,因此没有任何效果.

I have customized in WooCommerce plugin this core file includes\admin\meta-boxes\views\html-order-item and I am a little worried about future plugin updates (Are my custom changes will stay preserved or not). I have tried to copy this file in my child theme inside the woocommerce folder, but it's not seems to override the original one, so it has no effect.

在此"html-order-item.php"文件中,我刚刚添加了一小段代码,其中包含一个下载按钮,用于下载产品的原始图像.

In this "html-order-item.php" file, I have just added a small piece of code which has a download button to downloads product's original image.

如何使用干净的推荐方法(使用钩子/过滤器或模板)来实现这一目标?"
请提出任何实现它的方法.

How can I achieve this using a "clean recommended way ( using hooks/filters or templates)?
Please suggest any way to achieve it.

这是我的代码段(我的自定义以 /* Custom code added by Amol */ 开头):

Here is my code snippet (my customization starts with /* 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-(发现了问题,请参见代码中的注释)-

— Code updated 2 — (FOUND THE PROBLEMS, see comments in code)

只要在 html-order-item.php 核心文件中的自定义代码下,如果您查看现有代码,便会具有 woocommerce_admin_order_item_values 钩子,可将其用于代码,而不是覆盖WooCommerce核心文件.

Just under your custom code in html-order-item.php core file, if you take a look to existing code, you have woocommerce_admin_order_item_values hook that you can use for your code, instead overriding a WooCommerce core file.

但是您还需要使用 woocommerce_admin_order_item_headers ,如下面在我的代码段中所见……

But you will also need to use woocommerce_admin_order_item_headers as you will see below in my code snippets…

因为是,您将在更新WooCommerce时在该PHP文件中放弃代码自定义.这就是为什么您会在WordPress和WooCommerce核心文件中随处可见许多用于定制的钩子的情况.

Because YES you are going to loose your code customization in that PHP file when WooCommerce will be updated. That's why you will find everywhere in WordPress and WooCommerce core files a lot of different hooks to use, for customizations.

您不能将此核心文件复制到活动的子主题(或活动主题),并且这样做不会对其产生任何影响.

You can NOT copy this core files to your active child theme (or active theme) and doing this will not have any effect on it.

您可以做的是将WooCommerce插件中的 templates 文件夹复制到您的活动子主题(或活动主题),并将其重命名为 woocommerce .这样,您可以通过主题 覆盖WooCommerce模板,如本文档此处所述 .

What you can do is copy the templates folder located in WooCommerce plugin, to your active child theme (or active theme) and rename it woocommerce. This way you can override the WooCommerce templates via your theme, as explained here in this documentation.

现在,首先您要替换掉插件中的原始核心文件.

Now, first you are going to replace back the original core file in the plugin.

在您的子主题中,通常会有一个function.php文件,您将在其中添加以下代码(一个挂钩函数):

In your child theme, you normally have a function.php file where you are going to add the code below (a hooked function):

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
        );

 }

在项目metabox上的Admin Order编辑页面中,您将看到:

In Admin Order edit pages on item metabox you will see:

代码进入您的活动子主题(活动主题或任何插件文件)的function.php文件中.

Code goes in function.php file of your active child theme (active theme or in any plugin file).

此代码已经过测试并且可以正常工作.

This code is tested and works.

这篇关于自定义WooCommerce管理员快速订单预览中的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆