wordpress 在WooCommerce管理员快速订单预览中自定义内容

xoefb8l8  于 2023-05-28  发布在  WordPress
关注(0)|答案(1)|浏览(131)

我是新的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>

先谢谢你了。

mnemlml8

mnemlml81#

-代码更新2 - (发现问题,参见代码中的注解) -

就在**html-order-item.php核心文件中的自定义代码下,如果您查看现有代码,您可以将woocommerce_admin_order_item_values钩子用于您的代码,而不是覆盖WooCommerce核心文件。
但是你还需要使用
woocommerce_admin_order_item_headers,正如你将在我下面的代码片段中看到的...
因为
是的,当WooCommerce更新时,您将在该PHP文件中放松代码自定义**。这就是为什么你会在WordPress和WooCommerce核心文件中找到很多不同的钩子,用于自定义。

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

您可以做的是将位于WooCommerce插件中的**templates文件夹复制到您的活动子主题(或活动主题)并将其重命名为woocommerce**。这样你就可以通过你的主题as explained here in this documentation覆盖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
        );

 }

在管理订单中,您将看到项目metabox的编辑页面:

代码放在你的活动子主题的functions.php文件中(活动主题或任何插件文件)。
这段代码是测试和工作.

相关问题