Plugins
This commit is contained in:
@@ -1,394 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Coupon Data
|
||||
*
|
||||
* Display the coupon data meta box.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Coupon_Data Class.
|
||||
*/
|
||||
class WC_Meta_Box_Coupon_Data {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
|
||||
|
||||
$coupon_id = absint( $post->ID );
|
||||
$coupon = new WC_Coupon( $coupon_id );
|
||||
|
||||
?>
|
||||
|
||||
<style type="text/css">
|
||||
#edit-slug-box, #minor-publishing-actions { display:none }
|
||||
</style>
|
||||
<div id="coupon_options" class="panel-wrap coupon_data">
|
||||
|
||||
<div class="wc-tabs-back"></div>
|
||||
|
||||
<ul class="coupon_data_tabs wc-tabs" style="display:none;">
|
||||
<?php
|
||||
$coupon_data_tabs = apply_filters(
|
||||
'woocommerce_coupon_data_tabs',
|
||||
array(
|
||||
'general' => array(
|
||||
'label' => __( 'General', 'woocommerce' ),
|
||||
'target' => 'general_coupon_data',
|
||||
'class' => 'general_coupon_data',
|
||||
),
|
||||
'usage_restriction' => array(
|
||||
'label' => __( 'Usage restriction', 'woocommerce' ),
|
||||
'target' => 'usage_restriction_coupon_data',
|
||||
'class' => '',
|
||||
),
|
||||
'usage_limit' => array(
|
||||
'label' => __( 'Usage limits', 'woocommerce' ),
|
||||
'target' => 'usage_limit_coupon_data',
|
||||
'class' => '',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $coupon_data_tabs as $key => $tab ) :
|
||||
?>
|
||||
<li class="<?php echo $key; ?>_options <?php echo $key; ?>_tab <?php echo implode( ' ', (array) $tab['class'] ); ?>">
|
||||
<a href="#<?php echo $tab['target']; ?>">
|
||||
<span><?php echo esc_html( $tab['label'] ); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<div id="general_coupon_data" class="panel woocommerce_options_panel">
|
||||
<?php
|
||||
|
||||
// Type.
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => 'discount_type',
|
||||
'label' => __( 'Discount type', 'woocommerce' ),
|
||||
'options' => wc_get_coupon_types(),
|
||||
'value' => $coupon->get_discount_type( 'edit' ),
|
||||
)
|
||||
);
|
||||
|
||||
// Amount.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'coupon_amount',
|
||||
'label' => __( 'Coupon amount', 'woocommerce' ),
|
||||
'placeholder' => wc_format_localized_price( 0 ),
|
||||
'description' => __( 'Value of the coupon.', 'woocommerce' ),
|
||||
'data_type' => 'percent' === $coupon->get_discount_type( 'edit' ) ? 'decimal' : 'price',
|
||||
'desc_tip' => true,
|
||||
'value' => $coupon->get_amount( 'edit' ),
|
||||
)
|
||||
);
|
||||
|
||||
// Free Shipping.
|
||||
if ( wc_shipping_enabled() ) {
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => 'free_shipping',
|
||||
'label' => __( 'Allow free shipping', 'woocommerce' ),
|
||||
// translators: %s: URL to free shipping document.
|
||||
'description' => sprintf( __( 'Check this box if the coupon grants free shipping. A <a href="%s" target="_blank">free shipping method</a> must be enabled in your shipping zone and be set to require "a valid free shipping coupon" (see the "Free Shipping Requires" setting).', 'woocommerce' ), 'https://woocommerce.com/document/free-shipping/' ),
|
||||
'value' => wc_bool_to_string( $coupon->get_free_shipping( 'edit' ) ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Expiry date.
|
||||
$expiry_date = $coupon->get_date_expires( 'edit' ) ? $coupon->get_date_expires( 'edit' )->date( 'Y-m-d' ) : '';
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'expiry_date',
|
||||
'value' => esc_attr( $expiry_date ),
|
||||
'label' => __( 'Coupon expiry date', 'woocommerce' ),
|
||||
'placeholder' => 'YYYY-MM-DD',
|
||||
'description' => __( 'The coupon will expire at 00:00:00 of this date.', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'class' => 'date-picker',
|
||||
'custom_attributes' => array(
|
||||
'pattern' => apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_coupon_options', $coupon->get_id(), $coupon );
|
||||
|
||||
?>
|
||||
</div>
|
||||
<div id="usage_restriction_coupon_data" class="panel woocommerce_options_panel">
|
||||
<?php
|
||||
|
||||
echo '<div class="options_group">';
|
||||
|
||||
// minimum spend.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'minimum_amount',
|
||||
'label' => __( 'Minimum spend', 'woocommerce' ),
|
||||
'placeholder' => __( 'No minimum', 'woocommerce' ),
|
||||
'description' => __( 'This field allows you to set the minimum spend (subtotal) allowed to use the coupon.', 'woocommerce' ),
|
||||
'data_type' => 'price',
|
||||
'desc_tip' => true,
|
||||
'value' => $coupon->get_minimum_amount( 'edit' ),
|
||||
)
|
||||
);
|
||||
|
||||
// maximum spend.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'maximum_amount',
|
||||
'label' => __( 'Maximum spend', 'woocommerce' ),
|
||||
'placeholder' => __( 'No maximum', 'woocommerce' ),
|
||||
'description' => __( 'This field allows you to set the maximum spend (subtotal) allowed when using the coupon.', 'woocommerce' ),
|
||||
'data_type' => 'price',
|
||||
'desc_tip' => true,
|
||||
'value' => $coupon->get_maximum_amount( 'edit' ),
|
||||
)
|
||||
);
|
||||
|
||||
// Individual use.
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => 'individual_use',
|
||||
'label' => __( 'Individual use only', 'woocommerce' ),
|
||||
'description' => __( 'Check this box if the coupon cannot be used in conjunction with other coupons.', 'woocommerce' ),
|
||||
'value' => wc_bool_to_string( $coupon->get_individual_use( 'edit' ) ),
|
||||
)
|
||||
);
|
||||
|
||||
// Exclude Sale Products.
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => 'exclude_sale_items',
|
||||
'label' => __( 'Exclude sale items', 'woocommerce' ),
|
||||
'description' => __( 'Check this box if the coupon should not apply to items on sale. Per-item coupons will only work if the item is not on sale. Per-cart coupons will only work if there are items in the cart that are not on sale.', 'woocommerce' ),
|
||||
'value' => wc_bool_to_string( $coupon->get_exclude_sale_items( 'edit' ) ),
|
||||
)
|
||||
);
|
||||
|
||||
echo '</div><div class="options_group">';
|
||||
|
||||
// Product ids.
|
||||
?>
|
||||
<p class="form-field">
|
||||
<label><?php _e( 'Products', 'woocommerce' ); ?></label>
|
||||
<select class="wc-product-search" multiple="multiple" style="width: 50%;" name="product_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations">
|
||||
<?php
|
||||
$product_ids = $coupon->get_product_ids( 'edit' );
|
||||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( is_object( $product ) ) {
|
||||
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php echo wc_help_tip( __( 'Products that the coupon will be applied to, or that need to be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
|
||||
<?php // Exclude Product ids. ?>
|
||||
<p class="form-field">
|
||||
<label><?php _e( 'Exclude products', 'woocommerce' ); ?></label>
|
||||
<select class="wc-product-search" multiple="multiple" style="width: 50%;" name="exclude_product_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations">
|
||||
<?php
|
||||
$product_ids = $coupon->get_excluded_product_ids( 'edit' );
|
||||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( is_object( $product ) ) {
|
||||
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php echo wc_help_tip( __( 'Products that the coupon will not be applied to, or that cannot be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
<?php
|
||||
|
||||
echo '</div><div class="options_group">';
|
||||
|
||||
// Categories.
|
||||
?>
|
||||
<p class="form-field">
|
||||
<label for="product_categories"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
|
||||
<select id="product_categories" name="product_categories[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any category', 'woocommerce' ); ?>">
|
||||
<?php
|
||||
$category_ids = $coupon->get_product_categories( 'edit' );
|
||||
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
|
||||
|
||||
if ( $categories ) {
|
||||
foreach ( $categories as $cat ) {
|
||||
echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . esc_html( $cat->name ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select> <?php echo wc_help_tip( __( 'Product categories that the coupon will be applied to, or that need to be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
|
||||
<?php // Exclude Categories. ?>
|
||||
<p class="form-field">
|
||||
<label for="exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
|
||||
<select id="exclude_product_categories" name="exclude_product_categories[]" style="width: 50%;" class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No categories', 'woocommerce' ); ?>">
|
||||
<?php
|
||||
$category_ids = $coupon->get_excluded_product_categories( 'edit' );
|
||||
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
|
||||
|
||||
if ( $categories ) {
|
||||
foreach ( $categories as $cat ) {
|
||||
echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . esc_html( $cat->name ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php echo wc_help_tip( __( 'Product categories that the coupon will not be applied to, or that cannot be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="options_group">
|
||||
<?php
|
||||
// Customers.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'customer_email',
|
||||
'label' => __( 'Allowed emails', 'woocommerce' ),
|
||||
'placeholder' => __( 'No restrictions', 'woocommerce' ),
|
||||
'description' => __( 'List of allowed billing emails to check against when an order is placed. Separate email addresses with commas. You can also use an asterisk (*) to match parts of an email. For example "*@gmail.com" would match all gmail addresses.', 'woocommerce' ),
|
||||
'value' => implode( ', ', (array) $coupon->get_email_restrictions( 'edit' ) ),
|
||||
'desc_tip' => true,
|
||||
'type' => 'email',
|
||||
'class' => '',
|
||||
'custom_attributes' => array(
|
||||
'multiple' => 'multiple',
|
||||
),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_coupon_options_usage_restriction', $coupon->get_id(), $coupon ); ?>
|
||||
</div>
|
||||
<div id="usage_limit_coupon_data" class="panel woocommerce_options_panel">
|
||||
<div class="options_group">
|
||||
<?php
|
||||
// Usage limit per coupons.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'usage_limit',
|
||||
'label' => __( 'Usage limit per coupon', 'woocommerce' ),
|
||||
'placeholder' => esc_attr__( 'Unlimited usage', 'woocommerce' ),
|
||||
'description' => __( 'How many times this coupon can be used before it is void.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'desc_tip' => true,
|
||||
'class' => 'short',
|
||||
'custom_attributes' => array(
|
||||
'step' => 1,
|
||||
'min' => 0,
|
||||
),
|
||||
'value' => $coupon->get_usage_limit( 'edit' ) ? $coupon->get_usage_limit( 'edit' ) : '',
|
||||
)
|
||||
);
|
||||
|
||||
// Usage limit per product.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'limit_usage_to_x_items',
|
||||
'label' => __( 'Limit usage to X items', 'woocommerce' ),
|
||||
'placeholder' => esc_attr__( 'Apply to all qualifying items in cart', 'woocommerce' ),
|
||||
'description' => __( 'The maximum number of individual items this coupon can apply to when using product discounts. Leave blank to apply to all qualifying items in cart.', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'class' => 'short',
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 1,
|
||||
'min' => 0,
|
||||
),
|
||||
'value' => $coupon->get_limit_usage_to_x_items( 'edit' ) ? $coupon->get_limit_usage_to_x_items( 'edit' ) : '',
|
||||
)
|
||||
);
|
||||
|
||||
// Usage limit per users.
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'usage_limit_per_user',
|
||||
'label' => __( 'Usage limit per user', 'woocommerce' ),
|
||||
'placeholder' => esc_attr__( 'Unlimited usage', 'woocommerce' ),
|
||||
'description' => __( 'How many times this coupon can be used by an individual user. Uses billing email for guests, and user ID for logged in users.', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'class' => 'short',
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 1,
|
||||
'min' => 0,
|
||||
),
|
||||
'value' => $coupon->get_usage_limit_per_user( 'edit' ) ? $coupon->get_usage_limit_per_user( 'edit' ) : '',
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_coupon_options_usage_limit', $coupon->get_id(), $coupon ); ?>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_coupon_data_panels', $coupon->get_id(), $coupon ); ?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function save( $post_id, $post ) {
|
||||
// Check for dupe coupons.
|
||||
$coupon_code = wc_format_coupon_code( $post->post_title );
|
||||
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $post_id );
|
||||
|
||||
if ( $id_from_code ) {
|
||||
WC_Admin_Meta_Boxes::add_error( __( 'Coupon code already exists - customers will use the latest coupon with this code.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$product_categories = isset( $_POST['product_categories'] ) ? (array) $_POST['product_categories'] : array();
|
||||
$exclude_product_categories = isset( $_POST['exclude_product_categories'] ) ? (array) $_POST['exclude_product_categories'] : array();
|
||||
|
||||
$coupon = new WC_Coupon( $post_id );
|
||||
$coupon->set_props(
|
||||
array(
|
||||
'code' => $post->post_title,
|
||||
'discount_type' => wc_clean( $_POST['discount_type'] ),
|
||||
'amount' => wc_format_decimal( $_POST['coupon_amount'] ),
|
||||
'date_expires' => wc_clean( $_POST['expiry_date'] ),
|
||||
'individual_use' => isset( $_POST['individual_use'] ),
|
||||
'product_ids' => isset( $_POST['product_ids'] ) ? array_filter( array_map( 'intval', (array) $_POST['product_ids'] ) ) : array(),
|
||||
'excluded_product_ids' => isset( $_POST['exclude_product_ids'] ) ? array_filter( array_map( 'intval', (array) $_POST['exclude_product_ids'] ) ) : array(),
|
||||
'usage_limit' => absint( $_POST['usage_limit'] ),
|
||||
'usage_limit_per_user' => absint( $_POST['usage_limit_per_user'] ),
|
||||
'limit_usage_to_x_items' => absint( $_POST['limit_usage_to_x_items'] ),
|
||||
'free_shipping' => isset( $_POST['free_shipping'] ),
|
||||
'product_categories' => array_filter( array_map( 'intval', $product_categories ) ),
|
||||
'excluded_product_categories' => array_filter( array_map( 'intval', $exclude_product_categories ) ),
|
||||
'exclude_sale_items' => isset( $_POST['exclude_sale_items'] ),
|
||||
'minimum_amount' => wc_format_decimal( $_POST['minimum_amount'] ),
|
||||
'maximum_amount' => wc_format_decimal( $_POST['maximum_amount'] ),
|
||||
'email_restrictions' => array_filter( array_map( 'trim', explode( ',', wc_clean( $_POST['customer_email'] ) ) ) ),
|
||||
)
|
||||
);
|
||||
$coupon->save();
|
||||
do_action( 'woocommerce_coupon_options_save', $post_id, $coupon );
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Actions
|
||||
*
|
||||
* Functions for displaying the order actions meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Internal\Admin\Orders\PageController;
|
||||
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Order_Actions Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Actions {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post|WC_Order $post Post or order object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $theorder;
|
||||
|
||||
OrderUtil::init_theorder_object( $post );
|
||||
$order = $theorder;
|
||||
|
||||
$order_id = $order->get_id();
|
||||
$order_actions = self::get_available_order_actions_for_order( $order );
|
||||
?>
|
||||
<ul class="order_actions submitbox">
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires at the start of order actions meta box rendering.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
do_action( 'woocommerce_order_actions_start', $order_id );
|
||||
?>
|
||||
|
||||
|
||||
<li class="wide" id="actions">
|
||||
<select name="wc_order_action">
|
||||
<option value=""><?php esc_html_e( 'Choose an action...', 'woocommerce' ); ?></option>
|
||||
<?php foreach ( $order_actions as $action => $title ) { ?>
|
||||
<option value="<?php echo esc_attr( $action ); ?>"><?php echo esc_html( $title ); ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<button class="button wc-reload"><span><?php esc_html_e( 'Apply', 'woocommerce' ); ?></span></button>
|
||||
</li>
|
||||
|
||||
<li class="wide">
|
||||
<div id="delete-action">
|
||||
<?php
|
||||
if ( current_user_can( 'delete_post', $order_id ) ) {
|
||||
|
||||
if ( ! EMPTY_TRASH_DAYS ) {
|
||||
$delete_text = __( 'Delete permanently', 'woocommerce' );
|
||||
} else {
|
||||
$delete_text = __( 'Move to Trash', 'woocommerce' );
|
||||
}
|
||||
?>
|
||||
<a class="submitdelete deletion" href="<?php echo esc_url( self::get_trash_or_delete_order_link( $order_id ) ); ?>"><?php echo esc_html( $delete_text ); ?></a>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="button save_order button-primary" name="save" value="<?php echo 'auto-draft' === $order->get_status() ? esc_attr__( 'Create', 'woocommerce' ) : esc_attr__( 'Update', 'woocommerce' ); ?>"><?php echo 'auto-draft' === $order->get_status() ? esc_html__( 'Create', 'woocommerce' ) : esc_html__( 'Update', 'woocommerce' ); ?></button>
|
||||
</li>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires at the end of order actions meta box rendering.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
do_action( 'woocommerce_order_actions_end', $order_id );
|
||||
?>
|
||||
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms a trash/delete order URL.
|
||||
*
|
||||
* @param int $order_id The order ID for which we want a trash/delete URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function get_trash_or_delete_order_link( int $order_id ): string {
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
$order_type = wc_get_order( $order_id )->get_type();
|
||||
$order_list_url = wc_get_container()->get( PageController::class )->get_base_page_url( $order_type );
|
||||
$trash_order_url = add_query_arg(
|
||||
array(
|
||||
'action' => 'trash',
|
||||
'id' => array( $order_id ),
|
||||
'_wp_http_referer' => $order_list_url,
|
||||
),
|
||||
$order_list_url
|
||||
);
|
||||
|
||||
return wp_nonce_url( $trash_order_url, 'bulk-orders' );
|
||||
}
|
||||
|
||||
return get_delete_post_link( $order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param WP_Post $post Post Object.
|
||||
*/
|
||||
public static function save( $post_id, $post ) {
|
||||
// Order data saved, now get it so we can manipulate status.
|
||||
$order = wc_get_order( $post_id );
|
||||
|
||||
// Handle button actions.
|
||||
if ( ! empty( $_POST['wc_order_action'] ) ) { // @codingStandardsIgnoreLine
|
||||
|
||||
$action = wc_clean( wp_unslash( $_POST['wc_order_action'] ) ); // @codingStandardsIgnoreLine
|
||||
|
||||
if ( 'send_order_details' === $action ) {
|
||||
do_action( 'woocommerce_before_resend_order_emails', $order, 'customer_invoice' );
|
||||
|
||||
// Send the customer invoice email.
|
||||
WC()->payment_gateways();
|
||||
WC()->shipping();
|
||||
WC()->mailer()->customer_invoice( $order );
|
||||
|
||||
// Note the event.
|
||||
$order->add_order_note( __( 'Order details manually sent to customer.', 'woocommerce' ), false, true );
|
||||
|
||||
do_action( 'woocommerce_after_resend_order_email', $order, 'customer_invoice' );
|
||||
|
||||
// Change the post saved message.
|
||||
add_filter( 'redirect_post_location', array( __CLASS__, 'set_email_sent_message' ) );
|
||||
|
||||
} elseif ( 'send_order_details_admin' === $action ) {
|
||||
|
||||
do_action( 'woocommerce_before_resend_order_emails', $order, 'new_order' );
|
||||
|
||||
WC()->payment_gateways();
|
||||
WC()->shipping();
|
||||
add_filter( 'woocommerce_new_order_email_allows_resend', '__return_true' );
|
||||
WC()->mailer()->emails['WC_Email_New_Order']->trigger( $order->get_id(), $order, true );
|
||||
remove_filter( 'woocommerce_new_order_email_allows_resend', '__return_true' );
|
||||
|
||||
do_action( 'woocommerce_after_resend_order_email', $order, 'new_order' );
|
||||
|
||||
// Change the post saved message.
|
||||
add_filter( 'redirect_post_location', array( __CLASS__, 'set_email_sent_message' ) );
|
||||
|
||||
} elseif ( 'regenerate_download_permissions' === $action ) {
|
||||
|
||||
$data_store = WC_Data_Store::load( 'customer-download' );
|
||||
$data_store->delete_by_order_id( $post_id );
|
||||
wc_downloadable_product_permissions( $post_id, true );
|
||||
|
||||
} else {
|
||||
|
||||
if ( ! did_action( 'woocommerce_order_action_' . sanitize_title( $action ) ) ) {
|
||||
do_action( 'woocommerce_order_action_' . sanitize_title( $action ), $order );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the correct message ID.
|
||||
*
|
||||
* @param string $location Location.
|
||||
* @since 2.3.0
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
public static function set_email_sent_message( $location ) {
|
||||
return add_query_arg( 'message', 11, $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the available order actions for a given order.
|
||||
*
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param WC_Order|null $order The order object or null if no order is available.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_available_order_actions_for_order( $order ) {
|
||||
$actions = array(
|
||||
'send_order_details' => __( 'Send order details to customer', 'woocommerce' ),
|
||||
'send_order_details_admin' => __( 'Resend new order notification', 'woocommerce' ),
|
||||
'regenerate_download_permissions' => __( 'Regenerate download permissions', 'woocommerce' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter: woocommerce_order_actions
|
||||
* Allows filtering of the available order actions for an order.
|
||||
*
|
||||
* @since 2.1.0 Filter was added.
|
||||
* @since 5.8.0 The $order param was added.
|
||||
*
|
||||
* @param array $actions The available order actions for the order.
|
||||
* @param WC_Order|null $order The order object or null if no order is available.
|
||||
*/
|
||||
return apply_filters( 'woocommerce_order_actions', $actions, $order );
|
||||
}
|
||||
}
|
||||
@@ -1,772 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Data
|
||||
*
|
||||
* Functions for displaying the order data meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.2.0
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Order_Data Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Data {
|
||||
|
||||
/**
|
||||
* Billing fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $billing_fields = array();
|
||||
|
||||
/**
|
||||
* Shipping fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $shipping_fields = array();
|
||||
|
||||
/**
|
||||
* Get billing fields for the meta box.
|
||||
*
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param string $context Context of fields (view or edit).
|
||||
* @return array
|
||||
*/
|
||||
protected static function get_billing_fields( $order = false, $context = 'edit' ) {
|
||||
/**
|
||||
* Provides an opportunity to modify the list of order billing fields displayed on the admin.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*
|
||||
* @param array Billing fields.
|
||||
* @param WC_Order|false $order Order object.
|
||||
* @param string $context Context of fields (view or edit).
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_admin_billing_fields',
|
||||
array(
|
||||
'first_name' => array(
|
||||
'label' => __( 'First name', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'last_name' => array(
|
||||
'label' => __( 'Last name', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'company' => array(
|
||||
'label' => __( 'Company', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'address_1' => array(
|
||||
'label' => __( 'Address line 1', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'address_2' => array(
|
||||
'label' => __( 'Address line 2', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'city' => array(
|
||||
'label' => __( 'City', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'postcode' => array(
|
||||
'label' => __( 'Postcode / ZIP', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'country' => array(
|
||||
'label' => __( 'Country / Region', 'woocommerce' ),
|
||||
'show' => false,
|
||||
'class' => 'js_field-country select short',
|
||||
'type' => 'select',
|
||||
'options' => array( '' => __( 'Select a country / region…', 'woocommerce' ) ) + WC()->countries->get_allowed_countries(),
|
||||
),
|
||||
'state' => array(
|
||||
'label' => __( 'State / County', 'woocommerce' ),
|
||||
'class' => 'js_field-state select short',
|
||||
'show' => false,
|
||||
),
|
||||
'email' => array(
|
||||
'label' => __( 'Email address', 'woocommerce' ),
|
||||
),
|
||||
'phone' => array(
|
||||
'label' => __( 'Phone', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
$order,
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shipping fields for the meta box.
|
||||
*
|
||||
* @param \WC_Order $order Order object.
|
||||
* @param string $context Context of fields (view or edit).
|
||||
* @return array
|
||||
*/
|
||||
protected static function get_shipping_fields( $order = false, $context = 'edit' ) {
|
||||
/**
|
||||
* Provides an opportunity to modify the list of order shipping fields displayed on the admin.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*
|
||||
* @param array Shipping fields.
|
||||
* @param WC_Order|false $order Order object.
|
||||
* @param string $context Context of fields (view or edit).
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_admin_shipping_fields',
|
||||
array(
|
||||
'first_name' => array(
|
||||
'label' => __( 'First name', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'last_name' => array(
|
||||
'label' => __( 'Last name', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'company' => array(
|
||||
'label' => __( 'Company', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'address_1' => array(
|
||||
'label' => __( 'Address line 1', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'address_2' => array(
|
||||
'label' => __( 'Address line 2', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'city' => array(
|
||||
'label' => __( 'City', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'postcode' => array(
|
||||
'label' => __( 'Postcode / ZIP', 'woocommerce' ),
|
||||
'show' => false,
|
||||
),
|
||||
'country' => array(
|
||||
'label' => __( 'Country / Region', 'woocommerce' ),
|
||||
'show' => false,
|
||||
'type' => 'select',
|
||||
'class' => 'js_field-country select short',
|
||||
'options' => array( '' => __( 'Select a country / region…', 'woocommerce' ) ) + WC()->countries->get_shipping_countries(),
|
||||
),
|
||||
'state' => array(
|
||||
'label' => __( 'State / County', 'woocommerce' ),
|
||||
'class' => 'js_field-state select short',
|
||||
'show' => false,
|
||||
),
|
||||
'phone' => array(
|
||||
'label' => __( 'Phone', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
$order,
|
||||
$context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init billing and shipping fields we display + save. Maintained for backwards compat.
|
||||
*/
|
||||
public static function init_address_fields() {
|
||||
self::$billing_fields = self::get_billing_fields();
|
||||
self::$shipping_fields = self::get_shipping_fields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post|WC_Order $post Post or order object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $theorder;
|
||||
|
||||
OrderUtil::init_theorder_object( $post );
|
||||
|
||||
$order = $theorder;
|
||||
|
||||
if ( WC()->payment_gateways() ) {
|
||||
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||
} else {
|
||||
$payment_gateways = array();
|
||||
}
|
||||
|
||||
$payment_method = $order->get_payment_method();
|
||||
|
||||
$order_type_object = get_post_type_object( $order->get_type() );
|
||||
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
|
||||
?>
|
||||
<style type="text/css">
|
||||
#post-body-content, #titlediv { display:none }
|
||||
</style>
|
||||
<div class="panel-wrap woocommerce">
|
||||
<input name="post_title" type="hidden" value="<?php echo esc_attr( empty( $order->get_title() ) ? __( 'Order', 'woocommerce' ) : $order->get_title() ); ?>" />
|
||||
<input name="post_status" type="hidden" value="<?php echo esc_attr( $order->get_status() ); ?>" />
|
||||
<div id="order_data" class="panel woocommerce-order-data">
|
||||
<h2 class="woocommerce-order-data__heading">
|
||||
<?php
|
||||
|
||||
printf(
|
||||
/* translators: 1: order type 2: order number */
|
||||
esc_html__( '%1$s #%2$s details', 'woocommerce' ),
|
||||
esc_html( $order_type_object->labels->singular_name ),
|
||||
esc_html( $order->get_order_number() )
|
||||
);
|
||||
|
||||
?>
|
||||
</h2>
|
||||
<p class="woocommerce-order-data__meta order_number">
|
||||
<?php
|
||||
|
||||
$meta_list = array();
|
||||
|
||||
if ( $payment_method && 'other' !== $payment_method ) {
|
||||
$payment_method_string = sprintf(
|
||||
/* translators: %s: payment method */
|
||||
__( 'Payment via %s', 'woocommerce' ),
|
||||
esc_html( isset( $payment_gateways[ $payment_method ] ) ? $payment_gateways[ $payment_method ]->get_title() : $payment_method )
|
||||
);
|
||||
|
||||
$transaction_id = $order->get_transaction_id();
|
||||
if ( $transaction_id ) {
|
||||
|
||||
$to_add = null;
|
||||
if ( isset( $payment_gateways[ $payment_method ] ) ) {
|
||||
$url = $payment_gateways[ $payment_method ]->get_transaction_url( $order );
|
||||
if ( $url ) {
|
||||
$to_add .= ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)';
|
||||
}
|
||||
}
|
||||
|
||||
$to_add = $to_add ?? ' (' . esc_html( $transaction_id ) . ')';
|
||||
$payment_method_string .= $to_add;
|
||||
}
|
||||
|
||||
$meta_list[] = $payment_method_string;
|
||||
}
|
||||
|
||||
if ( $order->get_date_paid() ) {
|
||||
$meta_list[] = sprintf(
|
||||
/* translators: 1: date 2: time */
|
||||
__( 'Paid on %1$s @ %2$s', 'woocommerce' ),
|
||||
wc_format_datetime( $order->get_date_paid() ),
|
||||
wc_format_datetime( $order->get_date_paid(), get_option( 'time_format' ) )
|
||||
);
|
||||
}
|
||||
|
||||
$ip_address = $order->get_customer_ip_address();
|
||||
if ( $ip_address ) {
|
||||
$meta_list[] = sprintf(
|
||||
/* translators: %s: IP address */
|
||||
__( 'Customer IP: %s', 'woocommerce' ),
|
||||
'<span class="woocommerce-Order-customerIP">' . esc_html( $ip_address ) . '</span>'
|
||||
);
|
||||
}
|
||||
|
||||
echo wp_kses_post( implode( '. ', $meta_list ) );
|
||||
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
/**
|
||||
* Hook allowing extenders to render custom content
|
||||
* within the Order details box.
|
||||
*
|
||||
* This allows urgent notices or other important
|
||||
* order-related info to be displayed upfront in
|
||||
* the order page. Example: display a notice if
|
||||
* the order is disputed.
|
||||
*
|
||||
* @param $order WC_Order The order object being displayed.
|
||||
* @since 7.9.0
|
||||
*/
|
||||
do_action( 'woocommerce_admin_order_data_after_payment_info', $order );
|
||||
?>
|
||||
<div class="order_data_column_container">
|
||||
<div class="order_data_column">
|
||||
<h3><?php esc_html_e( 'General', 'woocommerce' ); ?></h3>
|
||||
|
||||
<p class="form-field form-field-wide">
|
||||
<?php
|
||||
$order_date_created_localised = ! is_null( $order->get_date_created() ) ? $order->get_date_created()->getOffsetTimestamp() : '';
|
||||
?>
|
||||
<label for="order_date"><?php esc_html_e( 'Date created:', 'woocommerce' ); ?></label>
|
||||
<input type="text" class="date-picker" name="order_date" maxlength="10" value="<?php echo esc_attr( date_i18n( 'Y-m-d', $order_date_created_localised ) ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment ?>" />@
|
||||
‎
|
||||
<input type="number" class="hour" placeholder="<?php esc_attr_e( 'h', 'woocommerce' ); ?>" name="order_date_hour" min="0" max="23" step="1" value="<?php echo esc_attr( date_i18n( 'H', $order_date_created_localised ) ); ?>" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:
|
||||
<input type="number" class="minute" placeholder="<?php esc_attr_e( 'm', 'woocommerce' ); ?>" name="order_date_minute" min="0" max="59" step="1" value="<?php echo esc_attr( date_i18n( 'i', $order_date_created_localised ) ); ?>" pattern="[0-5]{1}[0-9]{1}" />
|
||||
<input type="hidden" name="order_date_second" value="<?php echo esc_attr( date_i18n( 's', $order_date_created_localised ) ); ?>" />
|
||||
</p>
|
||||
|
||||
<p class="form-field form-field-wide wc-order-status">
|
||||
<label for="order_status">
|
||||
<?php
|
||||
esc_html_e( 'Status:', 'woocommerce' );
|
||||
if ( $order->needs_payment() ) {
|
||||
printf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $order->get_checkout_payment_url() ),
|
||||
esc_html__( 'Customer payment page →', 'woocommerce' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</label>
|
||||
<select id="order_status" name="order_status" class="wc-enhanced-select">
|
||||
<?php
|
||||
$statuses = wc_get_order_statuses();
|
||||
foreach ( $statuses as $status => $status_name ) {
|
||||
echo '<option value="' . esc_attr( $status ) . '" ' . selected( $status, 'wc-' . $order->get_status( 'edit' ), false ) . '>' . esc_html( $status_name ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<p class="form-field form-field-wide wc-customer-user">
|
||||
<!--email_off--> <!-- Disable CloudFlare email obfuscation -->
|
||||
<label for="customer_user">
|
||||
<?php
|
||||
esc_html_e( 'Customer:', 'woocommerce' );
|
||||
if ( $order->get_user_id( 'edit' ) ) {
|
||||
$args = array(
|
||||
'post_status' => 'all',
|
||||
'post_type' => 'shop_order',
|
||||
'_customer_user' => $order->get_user_id( 'edit' ),
|
||||
);
|
||||
printf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( add_query_arg( $args, admin_url( 'edit.php' ) ) ),
|
||||
' ' . esc_html__( 'View other orders →', 'woocommerce' )
|
||||
);
|
||||
printf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( add_query_arg( 'user_id', $order->get_user_id( 'edit' ), admin_url( 'user-edit.php' ) ) ),
|
||||
' ' . esc_html__( 'Profile →', 'woocommerce' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</label>
|
||||
<?php
|
||||
$user_string = '';
|
||||
$user_id = '';
|
||||
if ( $order->get_user_id() ) {
|
||||
$user_id = absint( $order->get_user_id() );
|
||||
$customer = new WC_Customer( $user_id );
|
||||
/* translators: 1: user display name 2: user ID 3: user email */
|
||||
$user_string = sprintf(
|
||||
/* translators: 1: customer name, 2 customer id, 3: customer email */
|
||||
esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ),
|
||||
$customer->get_first_name() . ' ' . $customer->get_last_name(),
|
||||
$customer->get_id(),
|
||||
$customer->get_email()
|
||||
);
|
||||
}
|
||||
?>
|
||||
<select class="wc-customer-search" id="customer_user" name="customer_user" data-placeholder="<?php esc_attr_e( 'Guest', 'woocommerce' ); ?>" data-allow_clear="true">
|
||||
<?php
|
||||
// phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment
|
||||
/**
|
||||
* Filter to customize the display of the currently selected customer for an order in the order edit page.
|
||||
* This is the same filter used in the ajax call for customer search in the same metabox.
|
||||
*
|
||||
* @since 7.2.0 (this instance of the filter)
|
||||
*
|
||||
* @param array @user_info An array containing one item with the name and email of the user currently selected as the customer for the order.
|
||||
*/
|
||||
?>
|
||||
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo esc_html( htmlspecialchars( wp_kses_post( current( apply_filters( 'woocommerce_json_search_found_customers', array( $user_string ) ) ) ) ) ); ?></option>
|
||||
<?php // phpcs:enable WooCommerce.Commenting.CommentHooks.MissingHookComment ?>
|
||||
</select>
|
||||
<!--/email_off-->
|
||||
</p>
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment ?>
|
||||
</div>
|
||||
<div class="order_data_column">
|
||||
<h3>
|
||||
<?php esc_html_e( 'Billing', 'woocommerce' ); ?>
|
||||
<a href="#" class="edit_address"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a>
|
||||
<span>
|
||||
<a href="#" class="load_customer_billing" style="display:none;"><?php esc_html_e( 'Load billing address', 'woocommerce' ); ?></a>
|
||||
</span>
|
||||
</h3>
|
||||
<div class="address">
|
||||
<?php
|
||||
// Display values.
|
||||
if ( $order->get_formatted_billing_address() ) {
|
||||
echo '<p>' . wp_kses( $order->get_formatted_billing_address(), array( 'br' => array() ) ) . '</p>';
|
||||
} else {
|
||||
echo '<p class="none_set"><strong>' . esc_html__( 'Address:', 'woocommerce' ) . '</strong> ' . esc_html__( 'No billing address set.', 'woocommerce' ) . '</p>';
|
||||
}
|
||||
|
||||
$billing_fields = self::get_billing_fields( $order, 'view' );
|
||||
|
||||
foreach ( $billing_fields as $key => $field ) {
|
||||
if ( isset( $field['show'] ) && false === $field['show'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field_name = 'billing_' . $key;
|
||||
|
||||
if ( isset( $field['value'] ) ) {
|
||||
$field_value = $field['value'];
|
||||
} elseif ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||
$field_value = $order->{"get_$field_name"}( 'edit' );
|
||||
} else {
|
||||
$field_value = $order->get_meta( '_' . $field_name );
|
||||
}
|
||||
|
||||
if ( 'billing_phone' === $field_name ) {
|
||||
$field_value = wc_make_phone_clickable( $field_value );
|
||||
} elseif ( 'billing_email' === $field_name ) {
|
||||
$field_value = '<a href="' . esc_url( 'mailto:' . $field_value ) . '">' . $field_value . '</a>';
|
||||
} else {
|
||||
$field_value = make_clickable( esc_html( $field_value ) );
|
||||
}
|
||||
|
||||
if ( $field_value ) {
|
||||
echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . wp_kses_post( $field_value ) . '</p>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="edit_address">
|
||||
<?php
|
||||
// Display form.
|
||||
$billing_fields = self::get_billing_fields( $order, 'edit' );
|
||||
|
||||
foreach ( $billing_fields as $key => $field ) {
|
||||
if ( ! isset( $field['type'] ) ) {
|
||||
$field['type'] = 'text';
|
||||
}
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_billing_' . $key;
|
||||
}
|
||||
|
||||
$field_name = 'billing_' . $key;
|
||||
|
||||
if ( ! isset( $field['value'] ) ) {
|
||||
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||
$field['value'] = $order->{"get_$field_name"}( 'edit' );
|
||||
} else {
|
||||
$field['value'] = $order->get_meta( '_' . $field_name );
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $field['type'] ) {
|
||||
case 'select':
|
||||
woocommerce_wp_select( $field, $order );
|
||||
break;
|
||||
case 'checkbox':
|
||||
woocommerce_wp_checkbox( $field, $order );
|
||||
break;
|
||||
default:
|
||||
woocommerce_wp_text_input( $field, $order );
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<p class="form-field form-field-wide">
|
||||
<label><?php esc_html_e( 'Payment method:', 'woocommerce' ); ?></label>
|
||||
<select name="_payment_method" id="_payment_method" class="first">
|
||||
<option value=""><?php esc_html_e( 'N/A', 'woocommerce' ); ?></option>
|
||||
<?php
|
||||
$found_method = false;
|
||||
|
||||
foreach ( $payment_gateways as $gateway ) {
|
||||
if ( 'yes' === $gateway->enabled ) {
|
||||
echo '<option value="' . esc_attr( $gateway->id ) . '" ' . selected( $payment_method, $gateway->id, false ) . '>' . esc_html( $gateway->get_title() ) . '</option>';
|
||||
if ( $payment_method === $gateway->id ) {
|
||||
$found_method = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found_method && ! empty( $payment_method ) ) {
|
||||
echo '<option value="' . esc_attr( $payment_method ) . '" selected="selected">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
|
||||
} else {
|
||||
echo '<option value="other">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
<?php
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_transaction_id',
|
||||
'label' => __( 'Transaction ID', 'woocommerce' ),
|
||||
'value' => $order->get_transaction_id( 'edit' ),
|
||||
),
|
||||
$order
|
||||
);
|
||||
?>
|
||||
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_billing_address', $order ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment ?>
|
||||
</div>
|
||||
<div class="order_data_column">
|
||||
<h3>
|
||||
<?php esc_html_e( 'Shipping', 'woocommerce' ); ?>
|
||||
<a href="#" class="edit_address"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a>
|
||||
<span>
|
||||
<a href="#" class="load_customer_shipping" style="display:none;"><?php esc_html_e( 'Load shipping address', 'woocommerce' ); ?></a>
|
||||
<a href="#" class="billing-same-as-shipping" style="display:none;"><?php esc_html_e( 'Copy billing address', 'woocommerce' ); ?></a>
|
||||
</span>
|
||||
</h3>
|
||||
<div class="address">
|
||||
<?php
|
||||
// Display values.
|
||||
if ( $order->get_formatted_shipping_address() ) {
|
||||
echo '<p>' . wp_kses( $order->get_formatted_shipping_address(), array( 'br' => array() ) ) . '</p>';
|
||||
} else {
|
||||
echo '<p class="none_set"><strong>' . esc_html__( 'Address:', 'woocommerce' ) . '</strong> ' . esc_html__( 'No shipping address set.', 'woocommerce' ) . '</p>';
|
||||
}
|
||||
|
||||
$shipping_fields = self::get_shipping_fields( $order, 'view' );
|
||||
|
||||
if ( ! empty( $shipping_fields ) ) {
|
||||
foreach ( $shipping_fields as $key => $field ) {
|
||||
if ( isset( $field['show'] ) && false === $field['show'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field_name = 'shipping_' . $key;
|
||||
|
||||
if ( isset( $field['value'] ) ) {
|
||||
$field_value = $field['value'];
|
||||
} elseif ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||
$field_value = $order->{"get_$field_name"}( 'edit' );
|
||||
} else {
|
||||
$field_value = $order->get_meta( '_' . $field_name );
|
||||
}
|
||||
|
||||
if ( 'shipping_phone' === $field_name ) {
|
||||
$field_value = wc_make_phone_clickable( $field_value );
|
||||
}
|
||||
|
||||
if ( ! $field_value ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . wp_kses_post( $field_value ) . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
if ( apply_filters( 'woocommerce_enable_order_notes_field', 'yes' === get_option( 'woocommerce_enable_order_comments', 'yes' ) ) && $order->get_customer_note() ) { // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment
|
||||
echo '<p class="order_note"><strong>' . esc_html( __( 'Customer provided note:', 'woocommerce' ) ) . '</strong> ' . nl2br( esc_html( $order->get_customer_note() ) ) . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit_address">
|
||||
<?php
|
||||
// Display form.
|
||||
$shipping_fields = self::get_shipping_fields( $order, 'edit' );
|
||||
|
||||
if ( ! empty( $shipping_fields ) ) {
|
||||
foreach ( $shipping_fields as $key => $field ) {
|
||||
if ( ! isset( $field['type'] ) ) {
|
||||
$field['type'] = 'text';
|
||||
}
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_shipping_' . $key;
|
||||
}
|
||||
|
||||
$field_name = 'shipping_' . $key;
|
||||
|
||||
if ( ! isset( $field['value'] ) ) {
|
||||
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||
$field['value'] = $order->{"get_$field_name"}( 'edit' );
|
||||
} else {
|
||||
$field['value'] = $order->get_meta( '_' . $field_name );
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $field['type'] ) {
|
||||
case 'select':
|
||||
woocommerce_wp_select( $field, $order );
|
||||
break;
|
||||
case 'checkbox':
|
||||
woocommerce_wp_checkbox( $field, $order );
|
||||
break;
|
||||
default:
|
||||
woocommerce_wp_text_input( $field, $order );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows 3rd parties to alter whether the customer note should be displayed on the admin.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param bool TRUE if the note should be displayed. FALSE otherwise.
|
||||
*/
|
||||
if ( apply_filters( 'woocommerce_enable_order_notes_field', 'yes' === get_option( 'woocommerce_enable_order_comments', 'yes' ) ) ) :
|
||||
?>
|
||||
<p class="form-field form-field-wide">
|
||||
<label for="customer_note"><?php esc_html_e( 'Customer provided note', 'woocommerce' ); ?>:</label>
|
||||
<textarea rows="1" cols="40" name="customer_note" tabindex="6" id="excerpt" placeholder="<?php esc_attr_e( 'Customer notes about the order', 'woocommerce' ); ?>"><?php echo wp_kses_post( $order->get_customer_note() ); ?></textarea>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_shipping_address', $order ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @throws Exception Required request data is missing.
|
||||
*/
|
||||
public static function save( $order_id ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
|
||||
if ( ! isset( $_POST['order_status'] ) ) {
|
||||
throw new Exception( __( 'Order status is missing.', 'woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['_payment_method'] ) ) {
|
||||
throw new Exception( __( 'Payment method is missing.', 'woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
// Ensure gateways are loaded in case they need to insert data into the emails.
|
||||
WC()->payment_gateways();
|
||||
WC()->shipping();
|
||||
|
||||
// Get order object.
|
||||
$order = wc_get_order( $order_id );
|
||||
$props = array();
|
||||
|
||||
// Create order key.
|
||||
if ( ! $order->get_order_key() ) {
|
||||
$props['order_key'] = wc_generate_order_key();
|
||||
}
|
||||
|
||||
// Update customer.
|
||||
$customer_id = isset( $_POST['customer_user'] ) ? absint( $_POST['customer_user'] ) : 0;
|
||||
if ( $customer_id !== $order->get_customer_id() ) {
|
||||
$props['customer_id'] = $customer_id;
|
||||
}
|
||||
|
||||
// Update billing fields.
|
||||
$billing_fields = self::get_billing_fields( $order, 'edit' );
|
||||
|
||||
if ( ! empty( $billing_fields ) ) {
|
||||
foreach ( $billing_fields as $key => $field ) {
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_billing_' . $key;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST[ $field['id'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
|
||||
|
||||
// Update a field if it includes an update callback.
|
||||
if ( isset( $field['update_callback'] ) ) {
|
||||
call_user_func( $field['update_callback'], $field['id'], $value, $order );
|
||||
} elseif ( is_callable( array( $order, 'set_billing_' . $key ) ) ) {
|
||||
$props[ 'billing_' . $key ] = $value;
|
||||
} else {
|
||||
$order->update_meta_data( $field['id'], $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update shipping fields.
|
||||
$shipping_fields = self::get_shipping_fields( $order, 'edit' );
|
||||
|
||||
if ( ! empty( $shipping_fields ) ) {
|
||||
foreach ( $shipping_fields as $key => $field ) {
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_shipping_' . $key;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST[ $field['id'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = isset( $_POST[ $field['id'] ] ) ? wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) : '';
|
||||
|
||||
// Update a field if it includes an update callback.
|
||||
if ( isset( $field['update_callback'] ) ) {
|
||||
call_user_func( $field['update_callback'], $field['id'], $value, $order );
|
||||
} elseif ( is_callable( array( $order, 'set_shipping_' . $key ) ) ) {
|
||||
$props[ 'shipping_' . $key ] = $value;
|
||||
} else {
|
||||
$order->update_meta_data( $field['id'], $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['_transaction_id'] ) ) {
|
||||
$props['transaction_id'] = wc_clean( wp_unslash( $_POST['_transaction_id'] ) );
|
||||
}
|
||||
|
||||
// Payment method handling.
|
||||
if ( $order->get_payment_method() !== wc_clean( wp_unslash( $_POST['_payment_method'] ) ) ) {
|
||||
$methods = WC()->payment_gateways->payment_gateways();
|
||||
$payment_method = wc_clean( wp_unslash( $_POST['_payment_method'] ) );
|
||||
$payment_method_title = $payment_method;
|
||||
|
||||
if ( isset( $methods ) && isset( $methods[ $payment_method ] ) ) {
|
||||
$payment_method_title = $methods[ $payment_method ]->get_title();
|
||||
}
|
||||
|
||||
if ( 'other' === $payment_method ) {
|
||||
$payment_method_title = esc_html__( 'Other', 'woocommerce' );
|
||||
}
|
||||
|
||||
$props['payment_method'] = $payment_method;
|
||||
$props['payment_method_title'] = $payment_method_title;
|
||||
}
|
||||
|
||||
// Update date.
|
||||
if ( empty( $_POST['order_date'] ) ) {
|
||||
$date = time();
|
||||
} else {
|
||||
if ( ! isset( $_POST['order_date_hour'] ) || ! isset( $_POST['order_date_minute'] ) || ! isset( $_POST['order_date_second'] ) ) {
|
||||
throw new Exception( __( 'Order date, hour, minute and/or second are missing.', 'woocommerce' ), 400 );
|
||||
}
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||
$date = gmdate( 'Y-m-d H:i:s', strtotime( $_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':' . (int) $_POST['order_date_second'] ) );
|
||||
}
|
||||
|
||||
$props['date_created'] = $date;
|
||||
|
||||
// Set created via prop if new post.
|
||||
if ( isset( $_POST['original_post_status'] ) && 'auto-draft' === $_POST['original_post_status'] ) {
|
||||
$props['created_via'] = 'admin';
|
||||
}
|
||||
|
||||
// Customer note.
|
||||
if ( isset( $_POST['customer_note'] ) ) {
|
||||
$props['customer_note'] = sanitize_textarea_field( wp_unslash( $_POST['customer_note'] ) );
|
||||
}
|
||||
|
||||
// Save order data.
|
||||
$order->set_props( $props );
|
||||
$order->set_status( wc_clean( wp_unslash( $_POST['order_status'] ) ), '', true );
|
||||
$order->save();
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Downloads
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Order_Downloads Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Downloads {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WC_Order|WP_Post $post Post or order object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
if ( $post instanceof WC_Order ) {
|
||||
$order_id = $post->get_id();
|
||||
} else {
|
||||
$order_id = $post->ID;
|
||||
}
|
||||
?>
|
||||
<div class="order_download_permissions wc-metaboxes-wrapper">
|
||||
|
||||
<div class="wc-metaboxes">
|
||||
<?php
|
||||
$data_store = WC_Data_Store::load( 'customer-download' );
|
||||
$download_permissions = array();
|
||||
if ( 0 !== $order_id ) {
|
||||
$download_permissions = $data_store->get_downloads(
|
||||
array(
|
||||
'order_id' => $order_id,
|
||||
'orderby' => 'product_id',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$product = null;
|
||||
$loop = 0;
|
||||
$file_counter = 1;
|
||||
|
||||
if ( $download_permissions && count( $download_permissions ) > 0 ) {
|
||||
foreach ( $download_permissions as $download ) {
|
||||
if ( ! $product || $product->get_id() !== $download->get_product_id() ) {
|
||||
$product = wc_get_product( $download->get_product_id() );
|
||||
$file_counter = 1;
|
||||
}
|
||||
|
||||
// don't show permissions to files that have since been removed.
|
||||
if ( ! $product || ! $product->exists() || ! $product->has_file( $download->get_download_id() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Show file title instead of count if set.
|
||||
$file = $product->get_file( $download->get_download_id() );
|
||||
// translators: file name.
|
||||
$file_count = isset( $file['name'] ) ? $file['name'] : sprintf( __( 'File %d', 'woocommerce' ), $file_counter );
|
||||
|
||||
include __DIR__ . '/views/html-order-download-permission.php';
|
||||
|
||||
$loop++;
|
||||
$file_counter++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="toolbar">
|
||||
<p class="buttons">
|
||||
<select id="grant_access_id" class="wc-product-search" name="grant_access_id[]" multiple="multiple" style="width: 400px;" data-placeholder="<?php esc_attr_e( 'Search for a downloadable product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_downloadable_products_and_variations"></select>
|
||||
<button type="button" class="button grant_access">
|
||||
<?php esc_html_e( 'Grant access', 'woocommerce' ); ?>
|
||||
</button>
|
||||
</p>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function save( $post_id, $post ) {
|
||||
if ( isset( $_POST['permission_id'] ) ) {
|
||||
$permission_ids = $_POST['permission_id'];
|
||||
$downloads_remaining = $_POST['downloads_remaining'];
|
||||
$access_expires = $_POST['access_expires'];
|
||||
$max = max( array_keys( $permission_ids ) );
|
||||
|
||||
for ( $i = 0; $i <= $max; $i ++ ) {
|
||||
if ( ! isset( $permission_ids[ $i ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$download = new WC_Customer_Download( $permission_ids[ $i ] );
|
||||
$download->set_downloads_remaining( wc_clean( $downloads_remaining[ $i ] ) );
|
||||
$download->set_access_expires( array_key_exists( $i, $access_expires ) && '' !== $access_expires[ $i ] ? strtotime( $access_expires[ $i ] ) : '' );
|
||||
$download->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Data
|
||||
*
|
||||
* Functions for displaying the order items meta box.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Order_Items Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Items {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post|WC_Order $post Post or order object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $post, $thepostid, $theorder;
|
||||
|
||||
OrderUtil::init_theorder_object( $post );
|
||||
if ( ! is_int( $thepostid ) && ( $post instanceof WP_Post ) ) {
|
||||
$thepostid = $post->ID;
|
||||
}
|
||||
|
||||
$order = $theorder;
|
||||
$data = ( $post instanceof WP_Post ) ? get_post_meta( $post->ID ) : array();
|
||||
|
||||
include __DIR__ . '/views/html-order-items.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id
|
||||
*/
|
||||
public static function save( $post_id ) {
|
||||
/**
|
||||
* This $_POST variable's data has been validated and escaped
|
||||
* inside `wc_save_order_items()` function.
|
||||
*/
|
||||
wc_save_order_items( $post_id, $_POST );
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Notes
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Order_Notes Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Notes {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post|WC_Order $post Post or order object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
if ( $post instanceof WC_Order ) {
|
||||
$order_id = $post->get_id();
|
||||
} else {
|
||||
$order_id = $post->ID;
|
||||
}
|
||||
|
||||
$args = array( 'order_id' => $order_id );
|
||||
|
||||
if ( 0 !== $order_id ) {
|
||||
$notes = wc_get_order_notes( $args );
|
||||
} else {
|
||||
$notes = array();
|
||||
}
|
||||
|
||||
include __DIR__ . '/views/html-order-notes.php';
|
||||
?>
|
||||
<div class="add_note">
|
||||
<p>
|
||||
<label for="add_order_note"><?php esc_html_e( 'Add note', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'Add a note for your reference, or add a customer note (the user will be notified).', 'woocommerce' ) ); ?></label>
|
||||
<textarea type="text" name="order_note" id="add_order_note" class="input-text" cols="20" rows="5"></textarea>
|
||||
</p>
|
||||
<p>
|
||||
<label for="order_note_type" class="screen-reader-text"><?php esc_html_e( 'Note type', 'woocommerce' ); ?></label>
|
||||
<select name="order_note_type" id="order_note_type">
|
||||
<option value=""><?php esc_html_e( 'Private note', 'woocommerce' ); ?></option>
|
||||
<option value="customer"><?php esc_html_e( 'Note to customer', 'woocommerce' ); ?></option>
|
||||
</select>
|
||||
<button type="button" class="add_note button"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product Categories meta box
|
||||
*
|
||||
* Display the product categories meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 7.5.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Product_Categories Class.
|
||||
*/
|
||||
class WC_Meta_Box_Product_Categories {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post Current post object.
|
||||
* @param array $box {
|
||||
* Categories meta box arguments.
|
||||
*
|
||||
* @type string $id Meta box 'id' attribute.
|
||||
* @type string $title Meta box title.
|
||||
* @type callable $callback Meta box display callback.
|
||||
* @type array $args {
|
||||
* Extra meta box arguments.
|
||||
*
|
||||
* @type string $taxonomy Taxonomy. Default 'category'.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public static function output( $post, $box ) {
|
||||
$categories_count = (int) wp_count_terms( 'product_cat' );
|
||||
|
||||
/**
|
||||
* Filters the category metabox search threshold, for when to render the typeahead field.
|
||||
*
|
||||
* @since 7.6.0
|
||||
*
|
||||
* @param number $threshold The default threshold.
|
||||
* @returns number The threshold that will be used.
|
||||
*/
|
||||
if ( $categories_count <= apply_filters( 'woocommerce_product_category_metabox_search_threshold', 5 ) && function_exists( 'post_categories_meta_box' ) ) {
|
||||
return post_categories_meta_box( $post, $box );
|
||||
}
|
||||
|
||||
$defaults = array( 'taxonomy' => 'category' );
|
||||
if ( ! isset( $box['args'] ) || ! is_array( $box['args'] ) ) {
|
||||
$args = array();
|
||||
} else {
|
||||
$args = $box['args'];
|
||||
}
|
||||
$parsed_args = wp_parse_args( $args, $defaults );
|
||||
$tax_name = $parsed_args['taxonomy'];
|
||||
$selected_categories = wp_get_object_terms( $post->ID, 'product_cat' );
|
||||
?>
|
||||
<div id="taxonomy-<?php echo esc_attr( $tax_name ); ?>-metabox"></div>
|
||||
<?php foreach ( (array) $selected_categories as $term ) { ?>
|
||||
<input
|
||||
type="hidden"
|
||||
value="<?php echo esc_attr( $term->term_id ); ?>"
|
||||
name="tax_input[<?php esc_attr( $tax_name ); ?>][]"
|
||||
data-name="<?php echo esc_attr( $term->name ); ?>"
|
||||
/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,574 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product Data
|
||||
*
|
||||
* Displays the product data box, tabbed, with several panels covering price, stock etc.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 3.0.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Product_Data Class.
|
||||
*/
|
||||
class WC_Meta_Box_Product_Data {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $thepostid, $product_object;
|
||||
|
||||
$thepostid = $post->ID;
|
||||
$product_object = $thepostid ? wc_get_product( $thepostid ) : new WC_Product();
|
||||
|
||||
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
|
||||
|
||||
include __DIR__ . '/views/html-product-data-panel.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show tab content/settings.
|
||||
*/
|
||||
private static function output_tabs() {
|
||||
global $post, $thepostid, $product_object;
|
||||
|
||||
include __DIR__ . '/views/html-product-data-general.php';
|
||||
include __DIR__ . '/views/html-product-data-inventory.php';
|
||||
include __DIR__ . '/views/html-product-data-shipping.php';
|
||||
include __DIR__ . '/views/html-product-data-linked-products.php';
|
||||
include __DIR__ . '/views/html-product-data-attributes.php';
|
||||
include __DIR__ . '/views/html-product-data-advanced.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of product type options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_product_type_options() {
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
return apply_filters(
|
||||
'product_type_options',
|
||||
wc_get_default_product_type_options(),
|
||||
);
|
||||
/* phpcs: enable */
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of tabs to show.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_product_data_tabs() {
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
$tabs = apply_filters(
|
||||
'woocommerce_product_data_tabs',
|
||||
array(
|
||||
'general' => array(
|
||||
'label' => __( 'General', 'woocommerce' ),
|
||||
'target' => 'general_product_data',
|
||||
'class' => array( 'hide_if_grouped' ),
|
||||
'priority' => 10,
|
||||
),
|
||||
'inventory' => array(
|
||||
'label' => __( 'Inventory', 'woocommerce' ),
|
||||
'target' => 'inventory_product_data',
|
||||
'class' => array( 'show_if_simple', 'show_if_variable', 'show_if_grouped', 'show_if_external' ),
|
||||
'priority' => 20,
|
||||
),
|
||||
'shipping' => array(
|
||||
'label' => __( 'Shipping', 'woocommerce' ),
|
||||
'target' => 'shipping_product_data',
|
||||
'class' => array( 'hide_if_virtual', 'hide_if_grouped', 'hide_if_external' ),
|
||||
'priority' => 30,
|
||||
),
|
||||
'linked_product' => array(
|
||||
'label' => __( 'Linked Products', 'woocommerce' ),
|
||||
'target' => 'linked_product_data',
|
||||
'class' => array(),
|
||||
'priority' => 40,
|
||||
),
|
||||
'attribute' => array(
|
||||
'label' => __( 'Attributes', 'woocommerce' ),
|
||||
'target' => 'product_attributes',
|
||||
'class' => array(),
|
||||
'priority' => 50,
|
||||
),
|
||||
'variations' => array(
|
||||
'label' => __( 'Variations', 'woocommerce' ),
|
||||
'target' => 'variable_product_options',
|
||||
'class' => array( 'show_if_variable' ),
|
||||
'priority' => 60,
|
||||
),
|
||||
'advanced' => array(
|
||||
'label' => __( 'Advanced', 'woocommerce' ),
|
||||
'target' => 'advanced_product_data',
|
||||
'class' => array(),
|
||||
'priority' => 70,
|
||||
),
|
||||
)
|
||||
);
|
||||
/* phpcs: enable */
|
||||
|
||||
// Sort tabs based on priority.
|
||||
uasort( $tabs, array( __CLASS__, 'product_data_tabs_sort' ) );
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to sort product data tabs on priority.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @param int $a First item.
|
||||
* @param int $b Second item.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function product_data_tabs_sort( $a, $b ) {
|
||||
if ( ! isset( $a['priority'], $b['priority'] ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( $a['priority'] === $b['priority'] ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a['priority'] < $b['priority'] ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter callback for finding variation attributes.
|
||||
*
|
||||
* @param WC_Product_Attribute $attribute Product attribute.
|
||||
* @return bool
|
||||
*/
|
||||
private static function filter_variation_attributes( $attribute ) {
|
||||
return true === $attribute->get_variation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter callback for finding non-variation attributes.
|
||||
*
|
||||
* @param WC_Product_Attribute $attribute Product attribute.
|
||||
* @return bool
|
||||
*/
|
||||
private static function filter_non_variation_attributes( $attribute ) {
|
||||
return false === $attribute->get_variation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show options for the variable product type.
|
||||
*/
|
||||
public static function output_variations() {
|
||||
global $post, $wpdb, $product_object;
|
||||
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
$variation_attributes = array_filter( $product_object->get_attributes(), array( __CLASS__, 'filter_variation_attributes' ) );
|
||||
$default_attributes = $product_object->get_default_attributes();
|
||||
$variations_count = absint( apply_filters( 'woocommerce_admin_meta_boxes_variations_count', $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation' AND post_status IN ('publish', 'private')", $post->ID ) ), $post->ID ) );
|
||||
$variations_per_page = absint( apply_filters( 'woocommerce_admin_meta_boxes_variations_per_page', 15 ) );
|
||||
$variations_total_pages = ceil( $variations_count / $variations_per_page );
|
||||
$modal_title = get_bloginfo( 'name' ) . __( ' says', 'woocommerce' );
|
||||
/* phpcs: enable */
|
||||
|
||||
include __DIR__ . '/views/html-product-data-variations.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare downloads for save.
|
||||
*
|
||||
* @param array $file_names File names.
|
||||
* @param array $file_urls File urls.
|
||||
* @param array $file_hashes File hashes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function prepare_downloads( $file_names, $file_urls, $file_hashes ) {
|
||||
$downloads = array();
|
||||
|
||||
if ( ! empty( $file_urls ) ) {
|
||||
$file_url_size = count( $file_urls );
|
||||
|
||||
for ( $i = 0; $i < $file_url_size; $i ++ ) {
|
||||
if ( ! empty( $file_urls[ $i ] ) ) {
|
||||
$downloads[] = array(
|
||||
'name' => wc_clean( $file_names[ $i ] ),
|
||||
'file' => wp_unslash( trim( $file_urls[ $i ] ) ),
|
||||
'download_id' => wc_clean( $file_hashes[ $i ] ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $downloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare children for save.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function prepare_children() {
|
||||
return isset( $_POST['grouped_products'] ) ? array_filter( array_map( 'intval', (array) $_POST['grouped_products'] ) ) : array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare attributes for save.
|
||||
*
|
||||
* @param array $data Attribute data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function prepare_attributes( $data = false ) {
|
||||
$attributes = array();
|
||||
|
||||
if ( ! $data ) {
|
||||
$data = stripslashes_deep( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
|
||||
if ( isset( $data['attribute_names'], $data['attribute_values'] ) ) {
|
||||
$attribute_names = $data['attribute_names'];
|
||||
$attribute_values = $data['attribute_values'];
|
||||
$attribute_visibility = isset( $data['attribute_visibility'] ) ? $data['attribute_visibility'] : array();
|
||||
$attribute_variation = isset( $data['attribute_variation'] ) ? $data['attribute_variation'] : array();
|
||||
$attribute_position = $data['attribute_position'];
|
||||
$attribute_names_max_key = max( array_keys( $attribute_names ) );
|
||||
|
||||
for ( $i = 0; $i <= $attribute_names_max_key; $i++ ) {
|
||||
if ( empty( $attribute_names[ $i ] ) || ! isset( $attribute_values[ $i ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$attribute_id = 0;
|
||||
$attribute_name = wc_clean( esc_html( $attribute_names[ $i ] ) );
|
||||
|
||||
if ( 'pa_' === substr( $attribute_name, 0, 3 ) ) {
|
||||
$attribute_id = wc_attribute_taxonomy_id_by_name( $attribute_name );
|
||||
}
|
||||
|
||||
$options = isset( $attribute_values[ $i ] ) ? $attribute_values[ $i ] : '';
|
||||
|
||||
if ( is_array( $options ) ) {
|
||||
// Term ids sent as array.
|
||||
$options = wp_parse_id_list( $options );
|
||||
} else {
|
||||
// Terms or text sent in textarea.
|
||||
$options = 0 < $attribute_id ? wc_sanitize_textarea( esc_html( wc_sanitize_term_text_based( $options ) ) ) : wc_sanitize_textarea( esc_html( $options ) );
|
||||
$options = wc_get_text_attributes( $options );
|
||||
}
|
||||
|
||||
if ( empty( $options ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attribute = new WC_Product_Attribute();
|
||||
$attribute->set_id( $attribute_id );
|
||||
$attribute->set_name( $attribute_name );
|
||||
$attribute->set_options( $options );
|
||||
$attribute->set_position( $attribute_position[ $i ] );
|
||||
$attribute->set_visible( isset( $attribute_visibility[ $i ] ) );
|
||||
$attribute->set_variation( isset( $attribute_variation[ $i ] ) );
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
$attributes[] = apply_filters( 'woocommerce_admin_meta_boxes_prepare_attribute', $attribute, $data, $i );
|
||||
/* phpcs: enable */
|
||||
}
|
||||
}
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare attributes for a specific variation or defaults.
|
||||
*
|
||||
* @param array $all_attributes List of attribute keys.
|
||||
* @param string $key_prefix Attribute key prefix.
|
||||
* @param int $index Attribute array index.
|
||||
* @return array
|
||||
*/
|
||||
private static function prepare_set_attributes( $all_attributes, $key_prefix = 'attribute_', $index = null ) {
|
||||
$attributes = array();
|
||||
|
||||
if ( $all_attributes ) {
|
||||
foreach ( $all_attributes as $attribute ) {
|
||||
if ( $attribute->get_variation() ) {
|
||||
$attribute_key = sanitize_title( $attribute->get_name() );
|
||||
|
||||
if ( ! is_null( $index ) ) {
|
||||
$value = isset( $_POST[ $key_prefix . $attribute_key ][ $index ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ][ $index ] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
} else {
|
||||
$value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
}
|
||||
|
||||
if ( $attribute->is_taxonomy() ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters.
|
||||
$value = sanitize_title( $value );
|
||||
} else {
|
||||
$value = html_entity_decode( wc_clean( $value ), ENT_QUOTES, get_bloginfo( 'charset' ) ); // WPCS: sanitization ok.
|
||||
}
|
||||
|
||||
$attributes[ $attribute_key ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id WP post id.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function save( $post_id, $post ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
// Process product type first so we have the correct class to run setters.
|
||||
$product_type = empty( $_POST['product-type'] ) ? WC_Product_Factory::get_product_type( $post_id ) : sanitize_title( wp_unslash( $_POST['product-type'] ) );
|
||||
$classname = WC_Product_Factory::get_product_classname( $post_id, $product_type ? $product_type : 'simple' );
|
||||
$product = new $classname( $post_id );
|
||||
$attributes = self::prepare_attributes();
|
||||
$stock = null;
|
||||
|
||||
// Handle stock changes.
|
||||
if ( isset( $_POST['_stock'] ) ) {
|
||||
if ( isset( $_POST['_original_stock'] ) && wc_stock_amount( $product->get_stock_quantity( 'edit' ) ) !== wc_stock_amount( wp_unslash( $_POST['_original_stock'] ) ) ) {
|
||||
/* translators: 1: product ID 2: quantity in stock */
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The stock has not been updated because the value has changed since editing. Product %1$d has %2$d units in stock.', 'woocommerce' ), $product->get_id(), $product->get_stock_quantity( 'edit' ) ) );
|
||||
} else {
|
||||
$stock = wc_stock_amount( wp_unslash( $_POST['_stock'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle dates.
|
||||
$date_on_sale_from = '';
|
||||
$date_on_sale_to = '';
|
||||
|
||||
// Force date from to beginning of day.
|
||||
if ( isset( $_POST['_sale_price_dates_from'] ) ) {
|
||||
$date_on_sale_from = wc_clean( wp_unslash( $_POST['_sale_price_dates_from'] ) );
|
||||
|
||||
if ( ! empty( $date_on_sale_from ) ) {
|
||||
$date_on_sale_from = date( 'Y-m-d 00:00:00', strtotime( $date_on_sale_from ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
||||
}
|
||||
}
|
||||
|
||||
// Force date to to the end of the day.
|
||||
if ( isset( $_POST['_sale_price_dates_to'] ) ) {
|
||||
$date_on_sale_to = wc_clean( wp_unslash( $_POST['_sale_price_dates_to'] ) );
|
||||
|
||||
if ( ! empty( $date_on_sale_to ) ) {
|
||||
$date_on_sale_to = date( 'Y-m-d 23:59:59', strtotime( $date_on_sale_to ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
||||
}
|
||||
}
|
||||
|
||||
$errors = $product->set_props(
|
||||
array(
|
||||
'sku' => isset( $_POST['_sku'] ) ? wc_clean( wp_unslash( $_POST['_sku'] ) ) : null,
|
||||
'purchase_note' => isset( $_POST['_purchase_note'] ) ? wp_kses_post( wp_unslash( $_POST['_purchase_note'] ) ) : '',
|
||||
'downloadable' => isset( $_POST['_downloadable'] ),
|
||||
'virtual' => isset( $_POST['_virtual'] ),
|
||||
'featured' => isset( $_POST['_featured'] ),
|
||||
'catalog_visibility' => isset( $_POST['_visibility'] ) ? wc_clean( wp_unslash( $_POST['_visibility'] ) ) : null,
|
||||
'tax_status' => isset( $_POST['_tax_status'] ) ? wc_clean( wp_unslash( $_POST['_tax_status'] ) ) : null,
|
||||
'tax_class' => isset( $_POST['_tax_class'] ) ? sanitize_title( wp_unslash( $_POST['_tax_class'] ) ) : null,
|
||||
'weight' => isset( $_POST['_weight'] ) ? wc_clean( wp_unslash( $_POST['_weight'] ) ) : null,
|
||||
'length' => isset( $_POST['_length'] ) ? wc_clean( wp_unslash( $_POST['_length'] ) ) : null,
|
||||
'width' => isset( $_POST['_width'] ) ? wc_clean( wp_unslash( $_POST['_width'] ) ) : null,
|
||||
'height' => isset( $_POST['_height'] ) ? wc_clean( wp_unslash( $_POST['_height'] ) ) : null,
|
||||
'shipping_class_id' => isset( $_POST['product_shipping_class'] ) ? absint( wp_unslash( $_POST['product_shipping_class'] ) ) : null,
|
||||
'sold_individually' => ! empty( $_POST['_sold_individually'] ),
|
||||
'upsell_ids' => isset( $_POST['upsell_ids'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['upsell_ids'] ) ) : array(),
|
||||
'cross_sell_ids' => isset( $_POST['crosssell_ids'] ) ? array_map( 'intval', (array) wp_unslash( $_POST['crosssell_ids'] ) ) : array(),
|
||||
'regular_price' => isset( $_POST['_regular_price'] ) ? wc_clean( wp_unslash( $_POST['_regular_price'] ) ) : null,
|
||||
'sale_price' => isset( $_POST['_sale_price'] ) ? wc_clean( wp_unslash( $_POST['_sale_price'] ) ) : null,
|
||||
'date_on_sale_from' => $date_on_sale_from,
|
||||
'date_on_sale_to' => $date_on_sale_to,
|
||||
'manage_stock' => ! empty( $_POST['_manage_stock'] ),
|
||||
'backorders' => isset( $_POST['_backorders'] ) ? wc_clean( wp_unslash( $_POST['_backorders'] ) ) : null,
|
||||
'stock_status' => isset( $_POST['_stock_status'] ) ? wc_clean( wp_unslash( $_POST['_stock_status'] ) ) : null,
|
||||
'stock_quantity' => $stock,
|
||||
'low_stock_amount' => isset( $_POST['_low_stock_amount'] ) && '' !== $_POST['_low_stock_amount'] ? wc_stock_amount( wp_unslash( $_POST['_low_stock_amount'] ) ) : '',
|
||||
'download_limit' => isset( $_POST['_download_limit'] ) && '' !== $_POST['_download_limit'] ? absint( wp_unslash( $_POST['_download_limit'] ) ) : '',
|
||||
'download_expiry' => isset( $_POST['_download_expiry'] ) && '' !== $_POST['_download_expiry'] ? absint( wp_unslash( $_POST['_download_expiry'] ) ) : '',
|
||||
// Those are sanitized inside prepare_downloads.
|
||||
'downloads' => self::prepare_downloads(
|
||||
isset( $_POST['_wc_file_names'] ) ? wp_unslash( $_POST['_wc_file_names'] ) : array(), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
isset( $_POST['_wc_file_urls'] ) ? wp_unslash( $_POST['_wc_file_urls'] ) : array(), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
isset( $_POST['_wc_file_hashes'] ) ? wp_unslash( $_POST['_wc_file_hashes'] ) : array() // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
),
|
||||
'product_url' => isset( $_POST['_product_url'] ) ? esc_url_raw( wp_unslash( $_POST['_product_url'] ) ) : '',
|
||||
'button_text' => isset( $_POST['_button_text'] ) ? wc_clean( wp_unslash( $_POST['_button_text'] ) ) : '',
|
||||
'children' => 'grouped' === $product_type ? self::prepare_children() : null,
|
||||
'reviews_allowed' => ! empty( $_POST['comment_status'] ) && 'open' === $_POST['comment_status'],
|
||||
'attributes' => $attributes,
|
||||
'default_attributes' => self::prepare_set_attributes( $attributes, 'default_attribute_' ),
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( $errors->get_error_message() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set props before save.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
do_action( 'woocommerce_admin_process_product_object', $product );
|
||||
|
||||
$product->save();
|
||||
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
$original_post_title = isset( $_POST['original_post_title'] ) ? wc_clean( wp_unslash( $_POST['original_post_title'] ) ) : '';
|
||||
$post_title = isset( $_POST['post_title'] ) ? wc_clean( wp_unslash( $_POST['post_title'] ) ) : '';
|
||||
|
||||
$product->get_data_store()->sync_variation_names( $product, $original_post_title, $post_title );
|
||||
}
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
do_action( 'woocommerce_process_product_meta_' . $product_type, $post_id );
|
||||
/* phpcs:enable WordPress.Security.NonceVerification.Missing and WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
}
|
||||
|
||||
/**
|
||||
* Save variation meta box data.
|
||||
*
|
||||
* @param int $post_id WP post id.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function save_variations( $post_id, $post ) {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( isset( $_POST['variable_post_id'] ) ) {
|
||||
$parent = wc_get_product( $post_id );
|
||||
$parent->set_default_attributes( self::prepare_set_attributes( $parent->get_attributes(), 'default_attribute_' ) );
|
||||
$parent->save();
|
||||
|
||||
$max_loop = max( array_keys( wp_unslash( $_POST['variable_post_id'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$data_store = $parent->get_data_store();
|
||||
$data_store->sort_all_product_variations( $parent->get_id() );
|
||||
$new_variation_menu_order_id = ! empty( $_POST['new_variation_menu_order_id'] ) ? wc_clean( wp_unslash( $_POST['new_variation_menu_order_id'] ) ) : false;
|
||||
$new_variation_menu_order_value = ! empty( $_POST['new_variation_menu_order_value'] ) ? wc_clean( wp_unslash( $_POST['new_variation_menu_order_value'] ) ) : false;
|
||||
|
||||
// Only perform this operation if setting menu order via the prompt.
|
||||
if ( $new_variation_menu_order_id && $new_variation_menu_order_value ) {
|
||||
/*
|
||||
* We need to gather all the variations with menu order that is
|
||||
* equal or greater than the menu order that is newly set and
|
||||
* increment them by one so that we can correctly insert the updated
|
||||
* variation menu order.
|
||||
*/
|
||||
$wpdb->query(
|
||||
$wpdb->prepare(
|
||||
"UPDATE {$wpdb->posts} SET menu_order = menu_order + 1 WHERE post_type = 'product_variation' AND post_parent = %d AND post_status = 'publish' AND menu_order >= %d AND ID != %d",
|
||||
$post_id,
|
||||
$new_variation_menu_order_value,
|
||||
$new_variation_menu_order_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for ( $i = 0; $i <= $max_loop; $i++ ) {
|
||||
|
||||
if ( ! isset( $_POST['variable_post_id'][ $i ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$variation_id = absint( $_POST['variable_post_id'][ $i ] );
|
||||
$variation = wc_get_product_object( 'variation', $variation_id );
|
||||
$stock = null;
|
||||
|
||||
// Handle stock changes.
|
||||
if ( isset( $_POST['variable_stock'], $_POST['variable_stock'][ $i ] ) ) {
|
||||
if ( isset( $_POST['variable_original_stock'], $_POST['variable_original_stock'][ $i ] ) && wc_stock_amount( $variation->get_stock_quantity( 'edit' ) ) !== wc_stock_amount( wp_unslash( $_POST['variable_original_stock'][ $i ] ) ) ) {
|
||||
/* translators: 1: product ID 2: quantity in stock */
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The stock has not been updated because the value has changed since editing. Product %1$d has %2$d units in stock.', 'woocommerce' ), $variation->get_id(), $variation->get_stock_quantity( 'edit' ) ) );
|
||||
} else {
|
||||
$stock = wc_stock_amount( wp_unslash( $_POST['variable_stock'][ $i ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle dates.
|
||||
$date_on_sale_from = '';
|
||||
$date_on_sale_to = '';
|
||||
|
||||
// Force date from to beginning of day.
|
||||
if ( isset( $_POST['variable_sale_price_dates_from'][ $i ] ) ) {
|
||||
$date_on_sale_from = wc_clean( wp_unslash( $_POST['variable_sale_price_dates_from'][ $i ] ) );
|
||||
|
||||
if ( ! empty( $date_on_sale_from ) ) {
|
||||
$date_on_sale_from = date( 'Y-m-d 00:00:00', strtotime( $date_on_sale_from ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
||||
}
|
||||
}
|
||||
|
||||
// Force date to to the end of the day.
|
||||
if ( isset( $_POST['variable_sale_price_dates_to'][ $i ] ) ) {
|
||||
$date_on_sale_to = wc_clean( wp_unslash( $_POST['variable_sale_price_dates_to'][ $i ] ) );
|
||||
|
||||
if ( ! empty( $date_on_sale_to ) ) {
|
||||
$date_on_sale_to = date( 'Y-m-d 23:59:59', strtotime( $date_on_sale_to ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
||||
}
|
||||
}
|
||||
|
||||
$errors = $variation->set_props(
|
||||
array(
|
||||
'status' => isset( $_POST['variable_enabled'][ $i ] ) ? 'publish' : 'private',
|
||||
'menu_order' => isset( $_POST['variation_menu_order'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variation_menu_order'][ $i ] ) ) : null,
|
||||
'regular_price' => isset( $_POST['variable_regular_price'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_regular_price'][ $i ] ) ) : null,
|
||||
'sale_price' => isset( $_POST['variable_sale_price'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_sale_price'][ $i ] ) ) : null,
|
||||
'virtual' => isset( $_POST['variable_is_virtual'][ $i ] ),
|
||||
'downloadable' => isset( $_POST['variable_is_downloadable'][ $i ] ),
|
||||
'date_on_sale_from' => $date_on_sale_from,
|
||||
'date_on_sale_to' => $date_on_sale_to,
|
||||
'description' => isset( $_POST['variable_description'][ $i ] ) ? wp_kses_post( wp_unslash( $_POST['variable_description'][ $i ] ) ) : null,
|
||||
'download_limit' => isset( $_POST['variable_download_limit'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_download_limit'][ $i ] ) ) : null,
|
||||
'download_expiry' => isset( $_POST['variable_download_expiry'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_download_expiry'][ $i ] ) ) : null,
|
||||
// Those are sanitized inside prepare_downloads.
|
||||
'downloads' => self::prepare_downloads(
|
||||
isset( $_POST['_wc_variation_file_names'][ $variation_id ] ) ? wp_unslash( $_POST['_wc_variation_file_names'][ $variation_id ] ) : array(), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
isset( $_POST['_wc_variation_file_urls'][ $variation_id ] ) ? wp_unslash( $_POST['_wc_variation_file_urls'][ $variation_id ] ) : array(), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
isset( $_POST['_wc_variation_file_hashes'][ $variation_id ] ) ? wp_unslash( $_POST['_wc_variation_file_hashes'][ $variation_id ] ) : array() // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
),
|
||||
'manage_stock' => isset( $_POST['variable_manage_stock'][ $i ] ),
|
||||
'stock_quantity' => $stock,
|
||||
'low_stock_amount' => isset( $_POST['variable_low_stock_amount'][ $i ] ) && '' !== $_POST['variable_low_stock_amount'][ $i ] ? wc_stock_amount( wp_unslash( $_POST['variable_low_stock_amount'][ $i ] ) ) : '',
|
||||
'backorders' => isset( $_POST['variable_backorders'], $_POST['variable_backorders'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_backorders'][ $i ] ) ) : null,
|
||||
'stock_status' => isset( $_POST['variable_stock_status'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_stock_status'][ $i ] ) ) : null,
|
||||
'image_id' => isset( $_POST['upload_image_id'][ $i ] ) ? wc_clean( wp_unslash( $_POST['upload_image_id'][ $i ] ) ) : null,
|
||||
'attributes' => self::prepare_set_attributes( $parent->get_attributes(), 'attribute_', $i ),
|
||||
'sku' => isset( $_POST['variable_sku'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_sku'][ $i ] ) ) : '',
|
||||
'weight' => isset( $_POST['variable_weight'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_weight'][ $i ] ) ) : '',
|
||||
'length' => isset( $_POST['variable_length'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_length'][ $i ] ) ) : '',
|
||||
'width' => isset( $_POST['variable_width'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_width'][ $i ] ) ) : '',
|
||||
'height' => isset( $_POST['variable_height'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_height'][ $i ] ) ) : '',
|
||||
'shipping_class_id' => isset( $_POST['variable_shipping_class'][ $i ] ) ? wc_clean( wp_unslash( $_POST['variable_shipping_class'][ $i ] ) ) : null,
|
||||
'tax_class' => isset( $_POST['variable_tax_class'][ $i ] ) ? sanitize_title( wp_unslash( $_POST['variable_tax_class'][ $i ] ) ) : null,
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( $errors->get_error_message() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set variation props before save.
|
||||
*
|
||||
* @param object $variation WC_Product_Variation object.
|
||||
* @param int $i
|
||||
* @since 3.8.0
|
||||
*/
|
||||
do_action( 'woocommerce_admin_process_variation_object', $variation, $i );
|
||||
|
||||
$variation->save();
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
do_action( 'woocommerce_save_product_variation', $variation_id, $i );
|
||||
/* phpcs: enable */
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product Images
|
||||
*
|
||||
* Display the product images meta box.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Product_Images Class.
|
||||
*/
|
||||
class WC_Meta_Box_Product_Images {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $thepostid, $product_object;
|
||||
|
||||
$thepostid = $post->ID;
|
||||
$product_object = $thepostid ? wc_get_product( $thepostid ) : new WC_Product();
|
||||
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
|
||||
?>
|
||||
<div id="product_images_container">
|
||||
<ul class="product_images">
|
||||
<?php
|
||||
$product_image_gallery = $product_object->get_gallery_image_ids( 'edit' );
|
||||
|
||||
$attachments = array_filter( $product_image_gallery );
|
||||
$update_meta = false;
|
||||
$updated_gallery_ids = array();
|
||||
|
||||
if ( ! empty( $attachments ) ) {
|
||||
foreach ( $attachments as $attachment_id ) {
|
||||
$attachment = wp_get_attachment_image( $attachment_id, 'thumbnail' );
|
||||
|
||||
// if attachment is empty skip.
|
||||
if ( empty( $attachment ) ) {
|
||||
$update_meta = true;
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<li class="image" data-attachment_id="<?php echo esc_attr( $attachment_id ); ?>">
|
||||
<?php echo $attachment; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<ul class="actions">
|
||||
<li><a href="#" class="delete tips" data-tip="<?php esc_attr_e( 'Delete image', 'woocommerce' ); ?>"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></li>
|
||||
</ul>
|
||||
<?php
|
||||
// Allow for extra info to be exposed or extra action to be executed for this attachment.
|
||||
do_action( 'woocommerce_admin_after_product_gallery_item', $thepostid, $attachment_id );
|
||||
?>
|
||||
</li>
|
||||
<?php
|
||||
|
||||
// rebuild ids to be saved.
|
||||
$updated_gallery_ids[] = $attachment_id;
|
||||
}
|
||||
|
||||
// need to update product meta to set new gallery ids
|
||||
if ( $update_meta ) {
|
||||
update_post_meta( $post->ID, '_product_image_gallery', implode( ',', $updated_gallery_ids ) );
|
||||
}
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
|
||||
<input type="hidden" id="product_image_gallery" name="product_image_gallery" value="<?php echo esc_attr( implode( ',', $updated_gallery_ids ) ); ?>" />
|
||||
|
||||
</div>
|
||||
<p class="add_product_images hide-if-no-js">
|
||||
<a href="#" data-choose="<?php esc_attr_e( 'Add images to product gallery', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Add to gallery', 'woocommerce' ); ?>" data-delete="<?php esc_attr_e( 'Delete image', 'woocommerce' ); ?>" data-text="<?php esc_attr_e( 'Delete', 'woocommerce' ); ?>"><?php esc_html_e( 'Add product gallery images', 'woocommerce' ); ?></a>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function save( $post_id, $post ) {
|
||||
$product_type = empty( $_POST['product-type'] ) ? WC_Product_Factory::get_product_type( $post_id ) : sanitize_title( stripslashes( $_POST['product-type'] ) );
|
||||
$classname = WC_Product_Factory::get_product_classname( $post_id, $product_type ? $product_type : 'simple' );
|
||||
$product = new $classname( $post_id );
|
||||
$attachment_ids = isset( $_POST['product_image_gallery'] ) ? array_filter( explode( ',', wc_clean( $_POST['product_image_gallery'] ) ) ) : array();
|
||||
|
||||
$product->set_gallery_image_ids( $attachment_ids );
|
||||
$product->save();
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product Reviews
|
||||
*
|
||||
* Functions for displaying product reviews data meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Product_Reviews
|
||||
*/
|
||||
class WC_Meta_Box_Product_Reviews {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param object $comment Comment being shown.
|
||||
*/
|
||||
public static function output( $comment ) {
|
||||
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
|
||||
|
||||
$current = get_comment_meta( $comment->comment_ID, 'rating', true );
|
||||
?>
|
||||
<select name="rating" id="rating">
|
||||
<?php
|
||||
for ( $rating = 1; $rating <= 5; $rating ++ ) {
|
||||
printf( '<option value="%1$s"%2$s>%1$s</option>', $rating, selected( $current, $rating, false ) ); // WPCS: XSS ok.
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data
|
||||
*
|
||||
* @param mixed $data Data to save.
|
||||
* @return mixed
|
||||
*/
|
||||
public static function save( $data ) {
|
||||
// Not allowed, return regular value without updating meta.
|
||||
if ( ! isset( $_POST['woocommerce_meta_nonce'], $_POST['rating'] ) || ! wp_verify_nonce( wp_unslash( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ) { // WPCS: input var ok, sanitization ok.
|
||||
return $data;
|
||||
}
|
||||
|
||||
if ( $_POST['rating'] > 5 || $_POST['rating'] < 0 ) { // WPCS: input var ok.
|
||||
return $data;
|
||||
}
|
||||
|
||||
$comment_id = $data['comment_ID'];
|
||||
|
||||
update_comment_meta( $comment_id, 'rating', intval( wp_unslash( $_POST['rating'] ) ) ); // WPCS: input var ok.
|
||||
|
||||
// Return regular value after updating.
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product Short Description
|
||||
*
|
||||
* Replaces the standard excerpt box.
|
||||
*
|
||||
* @package WooCommerce\Admin\Meta Boxes
|
||||
* @version 2.1.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC_Meta_Box_Product_Short_Description Class.
|
||||
*/
|
||||
class WC_Meta_Box_Product_Short_Description {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
|
||||
$settings = array(
|
||||
'textarea_name' => 'excerpt',
|
||||
'quicktags' => array( 'buttons' => 'em,strong,link' ),
|
||||
'tinymce' => array(
|
||||
'theme_advanced_buttons1' => 'bold,italic,strikethrough,separator,bullist,numlist,separator,blockquote,separator,justifyleft,justifycenter,justifyright,separator,link,unlink,separator,undo,redo,separator',
|
||||
'theme_advanced_buttons2' => '',
|
||||
),
|
||||
'editor_css' => '<style>#wp-excerpt-editor-container .wp-editor-area{height:175px; width:100%;}</style>',
|
||||
);
|
||||
|
||||
wp_editor( htmlspecialchars_decode( $post->post_excerpt, ENT_QUOTES ), 'excerpt', apply_filters( 'woocommerce_product_short_description_editor_settings', $settings ) );
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div class="wc-metabox closed">
|
||||
<h3 class="fixed">
|
||||
<button type="button" data-permission_id="<?php echo esc_attr( $download->get_id() ); ?>" rel="<?php echo esc_attr( $download->get_product_id() ) . ',' . esc_attr( $download->get_download_id() ); ?>" class="revoke_access button"><?php esc_html_e( 'Revoke access', 'woocommerce' ); ?></button>
|
||||
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
|
||||
<strong>
|
||||
<?php
|
||||
printf(
|
||||
'#%s — %s — %s: %s — ',
|
||||
esc_html( $product->get_id() ),
|
||||
esc_html( apply_filters( 'woocommerce_admin_download_permissions_title', $product->get_name(), $download->get_product_id(), $download->get_order_id(), $download->get_order_key(), $download->get_download_id() ) ),
|
||||
esc_html( $file_count ),
|
||||
esc_html( wc_get_filename_from_url( $product->get_file_download_path( $download->get_download_id() ) ) )
|
||||
);
|
||||
printf( _n( 'Downloaded %s time', 'Downloaded %s times', $download->get_download_count(), 'woocommerce' ), esc_html( $download->get_download_count() ) )
|
||||
?>
|
||||
</strong>
|
||||
</h3>
|
||||
<table cellpadding="0" cellspacing="0" class="wc-metabox-content">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label><?php esc_html_e( 'Downloads remaining', 'woocommerce' ); ?></label>
|
||||
<input type="hidden" name="permission_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" />
|
||||
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" />
|
||||
</td>
|
||||
<td>
|
||||
<label><?php esc_html_e( 'Access expires', 'woocommerce' ); ?></label>
|
||||
<input type="text" class="short date-picker" name="access_expires[<?php echo esc_attr( $loop ); ?>]" value="<?php echo ! is_null( $download->get_access_expires() ) ? esc_attr( date_i18n( 'Y-m-d', $download->get_access_expires()->getTimestamp() ) ) : ''; ?>" maxlength="10" placeholder="<?php esc_attr_e( 'Never', 'woocommerce' ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" />
|
||||
</td>
|
||||
<td>
|
||||
<label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label>
|
||||
<?php
|
||||
$download_link = add_query_arg(
|
||||
array(
|
||||
'download_file' => $download->get_product_id(),
|
||||
'order' => $download->get_order_key(),
|
||||
'email' => urlencode( $download->get_user_email() ),
|
||||
'key' => $download->get_download_id(),
|
||||
),
|
||||
trailingslashit( home_url() )
|
||||
);
|
||||
?>
|
||||
<a id="copy-download-link" class="button" href="<?php echo esc_url( $download_link ); ?>" data-tip="<?php esc_attr_e( 'Copied!', 'woocommerce' ); ?>" data-tip-failed="<?php esc_attr_e( 'Copying to clipboard failed. You should be able to right-click the button and copy.', 'woocommerce' ); ?>"><?php esc_html_e( 'Copy link', 'woocommerce' ); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<label><?php esc_html_e( 'Customer download log', 'woocommerce' ); ?></label>
|
||||
<?php
|
||||
$report_url = add_query_arg(
|
||||
'permission_id',
|
||||
rawurlencode( $download->get_id() ),
|
||||
admin_url( 'admin.php?page=wc-reports&tab=orders&report=downloads' )
|
||||
);
|
||||
echo '<a class="button" href="' . esc_url( $report_url ) . '">';
|
||||
esc_html_e( 'View report', 'woocommerce' );
|
||||
echo '</a>';
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows an order item fee
|
||||
*
|
||||
* @var object $item The item being displayed
|
||||
* @var int $item_id The id of the item being displayed
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<tr class="fee <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
|
||||
<td class="thumb"><div></div></td>
|
||||
|
||||
<td class="name">
|
||||
<div class="view">
|
||||
<?php echo esc_html( $item->get_name() ? $item->get_name() : __( 'Fee', 'woocommerce' ) ); ?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="text" placeholder="<?php esc_attr_e( 'Fee name', 'woocommerce' ); ?>" name="order_item_name[<?php echo absint( $item_id ); ?>]" value="<?php echo ( $item->get_name() ) ? esc_attr( $item->get_name() ) : ''; ?>" />
|
||||
<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 esc_attr( $item->get_tax_class() ); ?>" />
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_after_order_fee_item_name', $item_id, $item, null ); ?>
|
||||
</td>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
|
||||
|
||||
<td class="item_cost" width="1%"> </td>
|
||||
<td class="quantity" width="1%"> </td>
|
||||
|
||||
<td class="line_cost" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );
|
||||
|
||||
if ( $refunded = -1 * $order->get_total_refunded_for_item( $item_id, 'fee' ) ) {
|
||||
echo '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
|
||||
</div>
|
||||
<div class="refund" style="display: none;">
|
||||
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<?php
|
||||
if ( ( $tax_data = $item->get_taxes() ) && wc_tax_enabled() ) {
|
||||
foreach ( $order_taxes as $tax_item ) {
|
||||
$tax_item_id = $tax_item->get_rate_id();
|
||||
$tax_item_total = isset( $tax_data['total'][ $tax_item_id ] ) ? $tax_data['total'][ $tax_item_id ] : '';
|
||||
?>
|
||||
<td class="line_tax" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo ( '' !== $tax_item_total ) ? wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ) : '–';
|
||||
|
||||
if ( $refunded = -1 * $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'fee' ) ) {
|
||||
echo '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
|
||||
</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 esc_attr( 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">
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<div class="wc-order-edit-line-item-actions">
|
||||
<a class="edit-order-item" href="#"></a><a class="delete-order-item" href="#"></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows an order item meta
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
* @var object $item The item being displayed
|
||||
* @var int $item_id The id of the item being displayed
|
||||
*/
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$hidden_order_itemmeta = apply_filters(
|
||||
'woocommerce_hidden_order_itemmeta',
|
||||
array(
|
||||
'_qty',
|
||||
'_tax_class',
|
||||
'_product_id',
|
||||
'_variation_id',
|
||||
'_line_subtotal',
|
||||
'_line_subtotal_tax',
|
||||
'_line_total',
|
||||
'_line_tax',
|
||||
'method_id',
|
||||
'cost',
|
||||
'_reduced_stock',
|
||||
'_restock_refunded_items',
|
||||
)
|
||||
);
|
||||
?><div class="view">
|
||||
<?php
|
||||
$meta_data = $item->get_all_formatted_meta_data( '' );
|
||||
if ( $meta_data ) :
|
||||
?>
|
||||
<table cellspacing="0" class="display_meta">
|
||||
<?php
|
||||
foreach ( $meta_data as $meta_id => $meta ) :
|
||||
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<th><?php echo wp_kses_post( $meta->display_key ); ?>:</th>
|
||||
<td><?php echo wp_kses_post( force_balance_tags( $meta->display_value ) ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<table class="meta" cellspacing="0">
|
||||
<tbody class="meta_items">
|
||||
<?php if ( $meta_data ) : ?>
|
||||
<?php
|
||||
foreach ( $meta_data as $meta_id => $meta ) :
|
||||
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<tr data-meta_id="<?php echo esc_attr( $meta_id ); ?>">
|
||||
<td>
|
||||
<input type="text" maxlength="255" placeholder="<?php esc_attr_e( 'Name (required)', 'woocommerce' ); ?>" name="meta_key[<?php echo esc_attr( $item_id ); ?>][<?php echo esc_attr( $meta_id ); ?>]" value="<?php echo esc_attr( $meta->key ); ?>" />
|
||||
<textarea placeholder="<?php esc_attr_e( 'Value (required)', 'woocommerce' ); ?>" name="meta_value[<?php echo esc_attr( $item_id ); ?>][<?php echo esc_attr( $meta_id ); ?>]"><?php echo esc_textarea( rawurldecode( $meta->value ) ); ?></textarea>
|
||||
</td>
|
||||
<td width="1%"><button class="remove_order_item_meta button">×</button></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4"><button class="add_order_item_meta button"><?php esc_html_e( 'Add meta', 'woocommerce' ); ?></button></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1,188 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows an order item
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
* @var WC_Order_Item $item The item being displayed
|
||||
* @var int $item_id The id of the item being displayed
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
$product = $item->get_product();
|
||||
$product_link = $product ? admin_url( 'post.php?post=' . $item->get_product_id() . '&action=edit' ) : '';
|
||||
$thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $product->get_image( 'thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : '';
|
||||
$row_class = apply_filters( 'woocommerce_admin_html_order_item_class', ! empty( $class ) ? $class : '', $item, $order );
|
||||
?>
|
||||
<tr class="item <?php echo esc_attr( $row_class ); ?>" data-order_item_id="<?php echo esc_attr( $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->get_name() ); ?>">
|
||||
<?php
|
||||
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . wp_kses_post( $item->get_name() ) . '</a>' : '<div class="wc-order-item-name">' . wp_kses_post( $item->get_name() ) . '</div>';
|
||||
|
||||
if ( $product && $product->get_sku() ) {
|
||||
echo '<div class="wc-order-item-sku"><strong>' . esc_html__( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';
|
||||
}
|
||||
|
||||
if ( $item->get_variation_id() ) {
|
||||
echo '<div class="wc-order-item-variation"><strong>' . esc_html__( 'Variation ID:', 'woocommerce' ) . '</strong> ';
|
||||
if ( 'product_variation' === get_post_type( $item->get_variation_id() ) ) {
|
||||
echo esc_html( $item->get_variation_id() );
|
||||
} else {
|
||||
/* translators: %s: variation id */
|
||||
printf( esc_html__( '%s (No longer exists)', 'woocommerce' ), esc_html( $item->get_variation_id() ) );
|
||||
}
|
||||
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 esc_attr( $item->get_tax_class() ); ?>" />
|
||||
|
||||
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, $product ); ?>
|
||||
<?php require __DIR__ . '/html-order-item-meta.php'; ?>
|
||||
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, $product ); ?>
|
||||
</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
|
||||
echo wc_price( $order->get_item_subtotal( $item, false, true ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="quantity" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo '<small class="times">×</small> ' . esc_html( $item->get_quantity() );
|
||||
|
||||
$refunded_qty = -1 * $order->get_qty_refunded_for_item( $item_id );
|
||||
|
||||
if ( $refunded_qty ) {
|
||||
echo '<small class="refunded">' . esc_html( $refunded_qty * -1 ) . '</small>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
$step = apply_filters( 'woocommerce_quantity_input_step', '1', $product );
|
||||
|
||||
/**
|
||||
* Filter to change the product quantity stepping in the order editor of the admin area.
|
||||
*
|
||||
* @since 5.8.0
|
||||
* @param string $step The current step amount to be used in the quantity editor.
|
||||
* @param WC_Product $product The product that is being edited.
|
||||
* @param string $context The context in which the quantity editor is shown, 'edit' or 'refund'.
|
||||
*/
|
||||
$step_edit = apply_filters( 'woocommerce_quantity_input_step_admin', $step, $product, 'edit' );
|
||||
$step_refund = apply_filters( 'woocommerce_quantity_input_step_admin', $step, $product, 'refund' );
|
||||
|
||||
/**
|
||||
* Filter to change the product quantity minimum in the order editor of the admin area.
|
||||
*
|
||||
* @since 5.8.0
|
||||
* @param string $step The current minimum amount to be used in the quantity editor.
|
||||
* @param WC_Product $product The product that is being edited.
|
||||
* @param string $context The context in which the quantity editor is shown, 'edit' or 'refund'.
|
||||
*/
|
||||
$min_edit = apply_filters( 'woocommerce_quantity_input_min_admin', '0', $product, 'edit' );
|
||||
$min_refund = apply_filters( 'woocommerce_quantity_input_min_admin', '0', $product, 'refund' );
|
||||
?>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="number" step="<?php echo esc_attr( $step_edit ); ?>" min="<?php echo esc_attr( $min_edit ); ?>" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item->get_quantity() ); ?>" data-qty="<?php echo esc_attr( $item->get_quantity() ); ?>" size="4" class="quantity" />
|
||||
</div>
|
||||
<div class="refund" style="display: none;">
|
||||
<input type="number" step="<?php echo esc_attr( $step_refund ); ?>" min="<?php echo esc_attr( $min_refund ); ?>" max="<?php echo absint( $item->get_quantity() ); ?>" 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( $item->get_total() ); ?>">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
if ( $item->get_subtotal() !== $item->get_total() ) {
|
||||
/* translators: %s: discount amount */
|
||||
echo '<span class="wc-order-item-discount">' . sprintf( esc_html__( '%s discount', 'woocommerce' ), wc_price( wc_format_decimal( $item->get_subtotal() - $item->get_total(), '' ), array( 'currency' => $order->get_currency() ) ) ) . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
$refunded = -1 * $order->get_total_refunded_for_item( $item_id );
|
||||
|
||||
if ( $refunded ) {
|
||||
echo '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<div class="split-input">
|
||||
<div class="input">
|
||||
<label><?php esc_attr_e( 'Before discount', 'woocommerce' ); ?></label>
|
||||
<input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo esc_attr( wc_format_localized_price( $item->get_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 esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total="<?php echo esc_attr( wc_format_localized_price( $item->get_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 esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<?php
|
||||
$tax_data = wc_tax_enabled() ? $item->get_taxes() : false;
|
||||
|
||||
if ( $tax_data ) {
|
||||
foreach ( $order_taxes as $tax_item ) {
|
||||
$tax_item_id = $tax_item->get_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_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
} else {
|
||||
echo '–';
|
||||
}
|
||||
|
||||
$refunded = -1 * $order->get_tax_refunded_for_item( $item_id, $tax_item_id );
|
||||
|
||||
if ( $refunded ) {
|
||||
echo '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<div class="split-input">
|
||||
<div class="input">
|
||||
<label><?php esc_attr_e( 'Before 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 esc_attr( 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 esc_attr( 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 esc_attr( 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>
|
||||
@@ -1,489 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order items HTML for meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Allow plugins to determine whether refunds UI should be rendered in the template.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param bool $render_refunds If the refunds UI should be rendered.
|
||||
* @param int $order_id The Order ID.
|
||||
* @param WC_Order $order The Order object.
|
||||
*/
|
||||
$render_refunds = (bool) apply_filters( 'woocommerce_admin_order_should_render_refunds', 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ), $order->get_id(), $order );
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$payment_gateway = wc_get_payment_gateway_by_order( $order );
|
||||
$line_items = $order->get_items( apply_filters( 'woocommerce_admin_order_item_types', 'line_item' ) );
|
||||
$discounts = $order->get_items( 'discount' );
|
||||
$line_items_fee = $order->get_items( 'fee' );
|
||||
$line_items_shipping = $order->get_items( 'shipping' );
|
||||
|
||||
if ( wc_tax_enabled() ) {
|
||||
$order_taxes = $order->get_taxes();
|
||||
$tax_classes = WC_Tax::get_tax_classes();
|
||||
$classes_options = wc_get_product_tax_class_options();
|
||||
$show_tax_columns = count( $order_taxes ) === 1;
|
||||
}
|
||||
?>
|
||||
<div class="woocommerce_order_items_wrapper wc-order-items-editable">
|
||||
<table cellpadding="0" cellspacing="0" class="woocommerce_order_items">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="item sortable" colspan="2" data-sort="string-ins"><?php esc_html_e( 'Item', 'woocommerce' ); ?></th>
|
||||
<?php do_action( 'woocommerce_admin_order_item_headers', $order ); ?>
|
||||
<th class="item_cost sortable" data-sort="float"><?php esc_html_e( 'Cost', 'woocommerce' ); ?></th>
|
||||
<th class="quantity sortable" data-sort="int"><?php esc_html_e( 'Qty', 'woocommerce' ); ?></th>
|
||||
<th class="line_cost sortable" data-sort="float"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
|
||||
<?php
|
||||
if ( ! empty( $order_taxes ) ) :
|
||||
foreach ( $order_taxes as $tax_id => $tax_item ) :
|
||||
$tax_class = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] );
|
||||
$tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' );
|
||||
$column_label = ! empty( $tax_item['label'] ) ? $tax_item['label'] : __( 'Tax', 'woocommerce' );
|
||||
/* translators: %1$s: tax item name %2$s: tax class name */
|
||||
$column_tip = sprintf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $tax_item['name'], $tax_class_name );
|
||||
?>
|
||||
<th class="line_tax tips" data-tip="<?php echo esc_attr( $column_tip ); ?>">
|
||||
<?php echo esc_attr( $column_label ); ?>
|
||||
<input type="hidden" class="order-tax-id" name="order_taxes[<?php echo esc_attr( $tax_id ); ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>">
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<a class="delete-order-tax" href="#" data-rate_id="<?php echo esc_attr( $tax_id ); ?>"></a>
|
||||
<?php endif; ?>
|
||||
</th>
|
||||
<?php
|
||||
endforeach;
|
||||
endif;
|
||||
?>
|
||||
<th class="wc-order-edit-line-item" width="1%"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="order_line_items">
|
||||
<?php
|
||||
foreach ( $line_items as $item_id => $item ) {
|
||||
do_action( 'woocommerce_before_order_item_' . $item->get_type() . '_html', $item_id, $item, $order );
|
||||
|
||||
include __DIR__ . '/html-order-item.php';
|
||||
|
||||
do_action( 'woocommerce_order_item_' . $item->get_type() . '_html', $item_id, $item, $order );
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_line_items', $order->get_id() );
|
||||
?>
|
||||
</tbody>
|
||||
<tbody id="order_fee_line_items">
|
||||
<?php
|
||||
foreach ( $line_items_fee as $item_id => $item ) {
|
||||
include __DIR__ . '/html-order-fee.php';
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_fees', $order->get_id() );
|
||||
?>
|
||||
</tbody>
|
||||
<tbody id="order_shipping_line_items">
|
||||
<?php
|
||||
$shipping_methods = WC()->shipping() ? WC()->shipping()->load_shipping_methods() : array();
|
||||
foreach ( $line_items_shipping as $item_id => $item ) {
|
||||
include __DIR__ . '/html-order-shipping.php';
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_shipping', $order->get_id() );
|
||||
?>
|
||||
</tbody>
|
||||
<tbody id="order_refunds">
|
||||
<?php
|
||||
$refunds = $order->get_refunds();
|
||||
|
||||
if ( $refunds ) {
|
||||
foreach ( $refunds as $refund ) {
|
||||
include __DIR__ . '/html-order-refund.php';
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_refunds', $order->get_id() );
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="wc-order-data-row wc-order-totals-items wc-order-items-editable">
|
||||
<?php
|
||||
$coupons = $order->get_items( 'coupon' );
|
||||
if ( $coupons ) :
|
||||
?>
|
||||
<div class="wc-used-coupons">
|
||||
<ul class="wc_coupon_list">
|
||||
<li><strong><?php esc_html_e( 'Coupon(s)', 'woocommerce' ); ?></strong></li>
|
||||
<?php
|
||||
foreach ( $coupons as $item_id => $item ) :
|
||||
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) ); // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$class = $order->is_editable() ? 'code editable' : 'code';
|
||||
?>
|
||||
<li class="<?php echo esc_attr( $class ); ?>">
|
||||
<?php if ( $post_id ) : ?>
|
||||
<?php
|
||||
$post_url = apply_filters(
|
||||
'woocommerce_admin_order_item_coupon_url',
|
||||
add_query_arg(
|
||||
array(
|
||||
'post' => $post_id,
|
||||
'action' => 'edit',
|
||||
),
|
||||
admin_url( 'post.php' )
|
||||
),
|
||||
$item,
|
||||
$order
|
||||
);
|
||||
?>
|
||||
<a href="<?php echo esc_url( $post_url ); ?>" class="tips" data-tip="<?php echo esc_attr( wc_price( $item->get_discount(), array( 'currency' => $order->get_currency() ) ) ); ?>">
|
||||
<span><?php echo esc_html( $item->get_code() ); ?></span>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<span class="tips" data-tip="<?php echo esc_attr( wc_price( $item->get_discount(), array( 'currency' => $order->get_currency() ) ) ); ?>">
|
||||
<span><?php echo esc_html( $item->get_code() ); ?></span>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<a class="remove-coupon" href="javascript:void(0)" aria-label="Remove" data-code="<?php echo esc_attr( $item->get_code() ); ?>"></a>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<table class="wc-order-totals">
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Items Subtotal:', 'woocommerce' ); ?></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_subtotal(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if ( 0 < $order->get_total_discount() ) : ?>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Coupon(s):', 'woocommerce' ); ?></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">-
|
||||
<?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php if ( 0 < $order->get_total_fees() ) : ?>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Fees:', 'woocommerce' ); ?></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_total_fees(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_discount', $order->get_id() ); ?>
|
||||
|
||||
<?php if ( $order->get_shipping_methods() ) : ?>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Shipping:', 'woocommerce' ); ?></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_shipping', $order->get_id() ); ?>
|
||||
|
||||
<?php if ( wc_tax_enabled() ) : ?>
|
||||
<?php foreach ( $order->get_tax_totals() as $code => $tax_total ) : ?>
|
||||
<tr>
|
||||
<td class="label"><?php echo esc_html( $tax_total->label ); ?>:</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php
|
||||
// We use wc_round_tax_total here because tax may need to be round up or round down depending upon settings, whereas wc_price alone will always round it down.
|
||||
echo wc_price( wc_round_tax_total( $tax_total->amount ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_tax', $order->get_id() ); ?>
|
||||
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Order Total', 'woocommerce' ); ?>:</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<?php if ( in_array( $order->get_status(), array( 'processing', 'completed', 'refunded' ), true ) && ! empty( $order->get_date_paid() ) ) : ?>
|
||||
|
||||
<table class="wc-order-totals" style="border-top: 1px solid #999; margin-top:12px; padding-top:12px">
|
||||
<tr>
|
||||
<td class="<?php echo $order->get_total_refunded() ? 'label' : 'label label-highlight'; ?>"><?php esc_html_e( 'Paid', 'woocommerce' ); ?>: <br /></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_total(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="description">
|
||||
<?php
|
||||
if ( $order->get_payment_method_title() ) {
|
||||
/* translators: 1: payment date. 2: payment method */
|
||||
echo esc_html( sprintf( __( '%1$s via %2$s', 'woocommerce' ), $order->get_date_paid()->date_i18n( get_option( 'date_format' ) ), $order->get_payment_method_title() ) );
|
||||
} else {
|
||||
echo esc_html( $order->get_date_paid()->date_i18n( get_option( 'date_format' ) ) );
|
||||
}
|
||||
?>
|
||||
</span>
|
||||
</td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $order->get_total_refunded() ) : ?>
|
||||
<table class="wc-order-totals" style="border-top: 1px solid #999; margin-top:12px; padding-top:12px">
|
||||
<tr>
|
||||
<td class="label refunded-total"><?php esc_html_e( 'Refunded', 'woocommerce' ); ?>:</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total refunded-total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
|
||||
</tr>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_refunded', $order->get_id() ); ?>
|
||||
|
||||
<tr>
|
||||
<td class="label label-highlight"><?php esc_html_e( 'Net Payment', 'woocommerce' ); ?>:</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<table class="wc-order-totals">
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_total', $order->get_id() ); ?>
|
||||
</table>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle">
|
||||
<p class="add-items">
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<button type="button" class="button add-line-item"><?php esc_html_e( 'Add item(s)', 'woocommerce' ); ?></button>
|
||||
<?php if ( wc_coupons_enabled() ) : ?>
|
||||
<button type="button" class="button add-coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending payment"', 'woocommerce' ) ); ?> <?php esc_html_e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( $render_refunds ) : ?>
|
||||
<button type="button" class="button refund-items"><?php esc_html_e( 'Refund', 'woocommerce' ); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
// Allow adding custom buttons.
|
||||
do_action( 'woocommerce_order_item_add_action_buttons', $order );
|
||||
?>
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<button type="button" class="button button-primary calculate-action"><?php esc_html_e( 'Recalculate', 'woocommerce' ); ?></button>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="wc-order-data-row wc-order-add-item wc-order-data-row-toggle" style="display:none;">
|
||||
<button type="button" class="button add-order-item"><?php esc_html_e( 'Add product(s)', 'woocommerce' ); ?></button>
|
||||
<button type="button" class="button add-order-fee"><?php esc_html_e( 'Add fee', 'woocommerce' ); ?></button>
|
||||
<button type="button" class="button add-order-shipping"><?php esc_html_e( 'Add shipping', 'woocommerce' ); ?></button>
|
||||
<?php if ( wc_tax_enabled() ) : ?>
|
||||
<button type="button" class="button add-order-tax"><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
// Allow adding custom buttons.
|
||||
do_action( 'woocommerce_order_item_add_line_buttons', $order );
|
||||
?>
|
||||
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
|
||||
<button type="button" class="button button-primary save-action"><?php esc_html_e( 'Save', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
<?php if ( $render_refunds ) : ?>
|
||||
<div class="wc-order-data-row wc-order-refund-items wc-order-data-row-toggle" style="display: none;">
|
||||
<table class="wc-order-totals">
|
||||
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
|
||||
<tr>
|
||||
<td class="label"><label for="restock_refunded_items"><?php esc_html_e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td>
|
||||
<td class="total"><input type="checkbox" id="restock_refunded_items" name="restock_refunded_items" <?php checked( apply_filters( 'woocommerce_restock_refunded_items', true ) ); ?> /></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Amount already refunded', 'woocommerce' ); ?>:</td>
|
||||
<td class="total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Total available to refund', 'woocommerce' ); ?>:</td>
|
||||
<td class="total"><?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">
|
||||
<label for="refund_amount">
|
||||
<?php echo wc_help_tip( __( 'Refund the line items above. This will show the total amount to be refunded', 'woocommerce' ) ); ?>
|
||||
<?php esc_html_e( 'Refund amount', 'woocommerce' ); ?>:
|
||||
</label>
|
||||
</td>
|
||||
<td class="total">
|
||||
<input type="text" id="refund_amount" name="refund_amount" class="wc_input_price"
|
||||
<?php
|
||||
if ( wc_tax_enabled() ) {
|
||||
// If taxes are enabled, using this refund amount can cause issues due to taxes not being refunded also.
|
||||
// The refunds should be added to the line items, not the order as a whole.
|
||||
echo 'readonly';
|
||||
}
|
||||
?>
|
||||
/>
|
||||
<div class="clear"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">
|
||||
<label for="refund_reason">
|
||||
<?php echo wc_help_tip( __( 'Note: the refund reason will be visible by the customer.', 'woocommerce' ) ); ?>
|
||||
<?php esc_html_e( 'Reason for refund (optional):', 'woocommerce' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
<td class="total">
|
||||
<input type="text" id="refund_reason" name="refund_reason" />
|
||||
<div class="clear"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="clear"></div>
|
||||
<div class="refund-actions">
|
||||
<?php
|
||||
$refund_amount = '<span class="wc-order-refund-amount">' . wc_price( 0, array( 'currency' => $order->get_currency() ) ) . '</span>';
|
||||
$gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' );
|
||||
|
||||
if ( false !== $payment_gateway && $payment_gateway->can_refund_order( $order ) ) {
|
||||
/* translators: refund amount, gateway name */
|
||||
echo '<button type="button" class="button button-primary do-api-refund">' . sprintf( esc_html__( 'Refund %1$s via %2$s', 'woocommerce' ), wp_kses_post( $refund_amount ), esc_html( $gateway_name ) ) . '</button>';
|
||||
}
|
||||
?>
|
||||
<?php /* translators: refund amount */ ?>
|
||||
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( esc_html__( 'Refund %s manually', 'woocommerce' ), wp_kses_post( $refund_amount ) ); ?></button>
|
||||
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
|
||||
<input type="hidden" id="refunded_amount" name="refunded_amount" value="<?php echo esc_attr( $order->get_total_refunded() ); ?>" />
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<script type="text/template" id="tmpl-wc-modal-add-products">
|
||||
<div class="wc-backbone-modal">
|
||||
<div class="wc-backbone-modal-content">
|
||||
<section class="wc-backbone-modal-main" role="main">
|
||||
<header class="wc-backbone-modal-header">
|
||||
<h1><?php esc_html_e( 'Add products', 'woocommerce' ); ?></h1>
|
||||
<button class="modal-close modal-close-link dashicons dashicons-no-alt">
|
||||
<span class="screen-reader-text">Close modal panel</span>
|
||||
</button>
|
||||
</header>
|
||||
<article>
|
||||
<form action="" method="post">
|
||||
<table class="widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php
|
||||
$row = '
|
||||
<td><select class="wc-product-search" name="item_id" data-allow_clear="true" data-display_stock="true" data-exclude_type="variable" data-placeholder="' . esc_attr__( 'Search for a product…', 'woocommerce' ) . '"></select></td>
|
||||
<td><input type="number" step="1" min="0" max="9999" autocomplete="off" name="item_qty" placeholder="1" size="4" class="quantity" /></td>';
|
||||
?>
|
||||
<tbody data-row="<?php echo esc_attr( $row ); ?>">
|
||||
<tr>
|
||||
<?php echo $row; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</article>
|
||||
<footer>
|
||||
<div class="inner">
|
||||
<button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wc-backbone-modal-backdrop modal-close"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-wc-modal-add-tax">
|
||||
<div class="wc-backbone-modal">
|
||||
<div class="wc-backbone-modal-content">
|
||||
<section class="wc-backbone-modal-main" role="main">
|
||||
<header class="wc-backbone-modal-header">
|
||||
<h1><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></h1>
|
||||
<button class="modal-close modal-close-link dashicons dashicons-no-alt">
|
||||
<span class="screen-reader-text">Close modal panel</span>
|
||||
</button>
|
||||
</header>
|
||||
<article>
|
||||
<form action="" method="post">
|
||||
<table class="widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th><?php esc_html_e( 'Rate name', 'woocommerce' ); ?></th>
|
||||
<th><?php esc_html_e( 'Tax class', 'woocommerce' ); ?></th>
|
||||
<th><?php esc_html_e( 'Rate code', 'woocommerce' ); ?></th>
|
||||
<th><?php esc_html_e( 'Rate %', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php
|
||||
$rates = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates ORDER BY tax_rate_name LIMIT 100" );
|
||||
foreach ( $rates as $rate ) {
|
||||
echo '
|
||||
<tr>
|
||||
<td><input type="radio" id="add_order_tax_' . absint( $rate->tax_rate_id ) . '" name="add_order_tax" value="' . absint( $rate->tax_rate_id ) . '" /></td>
|
||||
<td><label for="add_order_tax_' . absint( $rate->tax_rate_id ) . '">' . esc_html( WC_Tax::get_rate_label( $rate ) ) . '</label></td>
|
||||
<td>' . ( isset( $classes_options[ $rate->tax_rate_class ] ) ? esc_html( $classes_options[ $rate->tax_rate_class ] ) : '-' ) . '</td>
|
||||
<td>' . esc_html( WC_Tax::get_rate_code( $rate ) ) . '</td>
|
||||
<td>' . esc_html( WC_Tax::get_rate_percent( $rate ) ) . '</td>
|
||||
</tr>
|
||||
';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<?php if ( absint( $wpdb->get_var( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates;" ) ) > 100 ) : ?>
|
||||
<p>
|
||||
<label for="manual_tax_rate_id"><?php esc_html_e( 'Or, enter tax rate ID:', 'woocommerce' ); ?></label><br/>
|
||||
<input type="number" name="manual_tax_rate_id" id="manual_tax_rate_id" step="1" placeholder="<?php esc_attr_e( 'Optional', 'woocommerce' ); ?>" />
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</article>
|
||||
<footer>
|
||||
<div class="inner">
|
||||
<button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
</footer>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wc-backbone-modal-backdrop modal-close"></div>
|
||||
</script>
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Order notes HTML for meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
?>
|
||||
<ul class="order_notes">
|
||||
<?php
|
||||
if ( $notes ) {
|
||||
foreach ( $notes as $note ) {
|
||||
$css_class = array( 'note' );
|
||||
$css_class[] = $note->customer_note ? 'customer-note' : '';
|
||||
$css_class[] = 'system' === $note->added_by ? 'system-note' : '';
|
||||
$css_class = apply_filters( 'woocommerce_order_note_class', array_filter( $css_class ), $note );
|
||||
?>
|
||||
<li rel="<?php echo absint( $note->id ); ?>" class="<?php echo esc_attr( implode( ' ', $css_class ) ); ?>">
|
||||
<div class="note_content">
|
||||
<?php echo wpautop( wptexturize( wp_kses_post( $note->content ) ) ); // @codingStandardsIgnoreLine ?>
|
||||
</div>
|
||||
<p class="meta">
|
||||
<abbr class="exact-date" title="<?php echo esc_attr( $note->date_created->date( 'Y-m-d H:i:s' ) ); ?>">
|
||||
<?php
|
||||
/* translators: %1$s: note date %2$s: note time */
|
||||
echo esc_html( sprintf( __( '%1$s at %2$s', 'woocommerce' ), $note->date_created->date_i18n( wc_date_format() ), $note->date_created->date_i18n( wc_time_format() ) ) );
|
||||
?>
|
||||
</abbr>
|
||||
<?php
|
||||
if ( 'system' !== $note->added_by ) :
|
||||
/* translators: %s: note author */
|
||||
echo esc_html( sprintf( ' ' . __( 'by %s', 'woocommerce' ), $note->added_by ) );
|
||||
endif;
|
||||
?>
|
||||
<a href="#" class="delete_note" role="button"><?php esc_html_e( 'Delete note', 'woocommerce' ); ?></a>
|
||||
</p>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<li class="no-items"><?php esc_html_e( 'There are no notes yet.', 'woocommerce' ); ?></li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
@@ -1,79 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Show order refund
|
||||
*
|
||||
* @var object $refund The refund object.
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$who_refunded = new WP_User( $refund->get_refunded_by() );
|
||||
?>
|
||||
<tr class="refund <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_refund_id="<?php echo esc_attr( $refund->get_id() ); ?>">
|
||||
<td class="thumb"><div></div></td>
|
||||
|
||||
<td class="name">
|
||||
<?php
|
||||
if ( $who_refunded->exists() ) {
|
||||
printf(
|
||||
/* translators: 1: refund id 2: refund date 3: username */
|
||||
esc_html__( 'Refund #%1$s - %2$s by %3$s', 'woocommerce' ),
|
||||
esc_html( $refund->get_id() ),
|
||||
esc_html( wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ) ),
|
||||
sprintf(
|
||||
'<abbr class="refund_by" title="%1$s">%2$s</abbr>',
|
||||
/* translators: 1: ID who refunded */
|
||||
sprintf( esc_attr__( 'ID: %d', 'woocommerce' ), absint( $who_refunded->ID ) ),
|
||||
esc_html( $who_refunded->display_name )
|
||||
)
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
/* translators: 1: refund id 2: refund date */
|
||||
esc_html__( 'Refund #%1$s - %2$s', 'woocommerce' ),
|
||||
esc_html( $refund->get_id() ),
|
||||
esc_html( wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ) )
|
||||
);
|
||||
}
|
||||
?>
|
||||
<?php if ( $refund->get_reason() ) : ?>
|
||||
<p class="description"><?php echo esc_html( $refund->get_reason() ); ?></p>
|
||||
<?php endif; ?>
|
||||
<input type="hidden" class="order_refund_id" name="order_refund_id[]" value="<?php echo esc_attr( $refund->get_id() ); ?>" />
|
||||
|
||||
<?php do_action( 'woocommerce_after_order_refund_item_name', $refund ); ?>
|
||||
</td>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_item_values', null, $refund, $refund->get_id() ); ?>
|
||||
|
||||
<td class="item_cost" width="1%"> </td>
|
||||
<td class="quantity" width="1%"> </td>
|
||||
|
||||
<td class="line_cost" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo wp_kses_post(
|
||||
wc_price( '-' . $refund->get_amount(), array( 'currency' => $refund->get_currency() ) )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<?php
|
||||
if ( wc_tax_enabled() ) :
|
||||
$total_taxes = count( $order_taxes );
|
||||
?>
|
||||
<?php for ( $i = 0; $i < $total_taxes; $i++ ) : ?>
|
||||
<td class="line_tax" width="1%"></td>
|
||||
<?php endfor; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<td class="wc-order-edit-line-item">
|
||||
<div class="wc-order-edit-line-item-actions">
|
||||
<a class="delete_refund" href="#"></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows a shipping line
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*
|
||||
* @var object $item The item being displayed
|
||||
* @var int $item_id The id of the item being displayed
|
||||
*
|
||||
* @package WooCommerce\Admin\Views
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<tr class="shipping <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
|
||||
<td class="thumb"><div></div></td>
|
||||
|
||||
<td class="name">
|
||||
<div class="view">
|
||||
<?php echo esc_html( $item->get_name() ? $item->get_name() : __( 'Shipping', 'woocommerce' ) ); ?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="hidden" name="shipping_method_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
|
||||
<input type="text" class="shipping_method_name" placeholder="<?php esc_attr_e( 'Shipping name', 'woocommerce' ); ?>" name="shipping_method_title[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_name() ); ?>" />
|
||||
<select class="shipping_method" name="shipping_method[<?php echo esc_attr( $item_id ); ?>]">
|
||||
<optgroup label="<?php esc_attr_e( 'Shipping method', 'woocommerce' ); ?>">
|
||||
<option value=""><?php esc_html_e( 'N/A', 'woocommerce' ); ?></option>
|
||||
<?php
|
||||
$found_method = false;
|
||||
|
||||
foreach ( $shipping_methods as $method ) {
|
||||
$is_active = $item->get_method_id() === $method->id;
|
||||
|
||||
echo '<option value="' . esc_attr( $method->id ) . '" ' . selected( true, $is_active, false ) . '>' . esc_html( $method->get_method_title() ) . '</option>';
|
||||
|
||||
if ( $is_active ) {
|
||||
$found_method = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found_method && $item->get_method_id() ) {
|
||||
echo '<option value="' . esc_attr( $item->get_method_id() ) . '" selected="selected">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
|
||||
} else {
|
||||
echo '<option value="other">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, null ); ?>
|
||||
<?php require __DIR__ . '/html-order-item-meta.php'; ?>
|
||||
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, null ); ?>
|
||||
</td>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
|
||||
|
||||
<td class="item_cost" width="1%"> </td>
|
||||
<td class="quantity" width="1%"> </td>
|
||||
|
||||
<td class="line_cost" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo wp_kses_post( wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ) );
|
||||
$refunded = -1 * $order->get_total_refunded_for_item( $item_id, 'shipping' );
|
||||
if ( $refunded ) {
|
||||
echo wp_kses_post( '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>' );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="text" name="shipping_cost[<?php echo esc_attr( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
|
||||
</div>
|
||||
<div class="refund" style="display: none;">
|
||||
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<?php
|
||||
$tax_data = $item->get_taxes();
|
||||
if ( $tax_data && wc_tax_enabled() ) {
|
||||
foreach ( $order_taxes as $tax_item ) {
|
||||
$tax_item_id = $tax_item->get_rate_id();
|
||||
$tax_item_total = isset( $tax_data['total'][ $tax_item_id ] ) ? $tax_data['total'][ $tax_item_id ] : '';
|
||||
?>
|
||||
<td class="line_tax" width="1%">
|
||||
<div class="view">
|
||||
<?php
|
||||
echo wp_kses_post( ( '' !== $tax_item_total ) ? wc_price( $tax_item_total, array( 'currency' => $order->get_currency() ) ) : '–' );
|
||||
$refunded = -1 * $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' );
|
||||
if ( $refunded ) {
|
||||
echo wp_kses_post( '<small class="refunded">' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>' );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
|
||||
</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 esc_attr( 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">
|
||||
<?php if ( $order->is_editable() ) : ?>
|
||||
<div class="wc-order-edit-line-item-actions">
|
||||
<a class="edit-order-item" href="#"></a><a class="delete-order-item" href="#"></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product attribute table for reuse.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="attribute_name">
|
||||
<label><?php esc_html_e( 'Name', 'woocommerce' ); ?>:</label>
|
||||
|
||||
<?php if ( $attribute->is_taxonomy() ) : ?>
|
||||
<strong><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong>
|
||||
<input type="hidden" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
|
||||
<?php else : ?>
|
||||
<input type="text" class="attribute_name" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" placeholder="<?php esc_attr_e( 'f.e. size or color', 'woocommerce' ); ?>" />
|
||||
<?php endif; ?>
|
||||
<input type="hidden" name="attribute_position[<?php echo esc_attr( $i ); ?>]" class="attribute_position" value="<?php echo esc_attr( $attribute->get_position() ); ?>" />
|
||||
</td>
|
||||
<td rowspan="3">
|
||||
<label><?php esc_html_e( 'Value(s)', 'woocommerce' ); ?>:</label>
|
||||
<?php
|
||||
if ( $attribute->is_taxonomy() && $attribute->get_taxonomy_object() ) {
|
||||
$attribute_taxonomy = $attribute->get_taxonomy_object();
|
||||
$attribute_types = wc_get_attribute_types();
|
||||
|
||||
if ( ! array_key_exists( $attribute_taxonomy->attribute_type, $attribute_types ) ) {
|
||||
$attribute_taxonomy->attribute_type = 'select';
|
||||
}
|
||||
|
||||
if ( 'select' === $attribute_taxonomy->attribute_type ) {
|
||||
$attribute_orderby = ! empty( $attribute_taxonomy->attribute_orderby ) ? $attribute_taxonomy->attribute_orderby : 'name';
|
||||
/**
|
||||
* Filter the length (number of terms) rendered in the list.
|
||||
*
|
||||
* @since 8.8.0
|
||||
* @param int $term_limit The maximum number of terms to display in the list.
|
||||
*/
|
||||
$term_limit = absint( apply_filters( 'woocommerce_admin_terms_metabox_datalimit', 50 ) );
|
||||
?>
|
||||
<select multiple="multiple"
|
||||
data-minimum_input_length="0"
|
||||
data-limit="<?php echo esc_attr( $term_limit ); ?>" data-return_id="id"
|
||||
data-placeholder="<?php esc_attr_e( 'Select values', 'woocommerce' ); ?>"
|
||||
data-orderby="<?php echo esc_attr( $attribute_orderby ); ?>"
|
||||
class="multiselect attribute_values wc-taxonomy-term-search"
|
||||
name="attribute_values[<?php echo esc_attr( $i ); ?>][]"
|
||||
data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>">
|
||||
<?php
|
||||
$selected_terms = $attribute->get_terms();
|
||||
if ( $selected_terms ) {
|
||||
foreach ( $selected_terms as $selected_term ) {
|
||||
/**
|
||||
* Filter the selected attribute term name.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @param string $name Name of selected term.
|
||||
* @param array $term The selected term object.
|
||||
*/
|
||||
echo '<option value="' . esc_attr( $selected_term->term_id ) . '" selected="selected">' . esc_html( apply_filters( 'woocommerce_product_attribute_term_name', $selected_term->name, $selected_term ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></button>
|
||||
<button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'woocommerce' ); ?></button>
|
||||
<button class="button fr plus add_new_attribute"><?php esc_html_e( 'Create value', 'woocommerce' ); ?></button>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to display custom attribute terms.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @param array|null $attribute_taxonomy Attribute taxonomy object.
|
||||
* @param number $i Attribute index.
|
||||
* @param WC_Product_Attribute $attribute Attribute object.
|
||||
*/
|
||||
do_action( 'woocommerce_product_option_terms', $attribute_taxonomy, $i, $attribute );
|
||||
} else {
|
||||
?>
|
||||
<textarea name="attribute_values[<?php echo esc_attr( $i ); ?>]" cols="5" rows="5"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label><input type="checkbox" class="woocommerce_attribute_visible_on_product_page checkbox" <?php checked( $attribute->get_visible(), true ); ?> name="attribute_visibility[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Visible on the product page', 'woocommerce' ); ?></label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="enable_variation show_if_variable">
|
||||
<label><input type="checkbox" class="woocommerce_attribute_used_for_variations checkbox" <?php checked( $attribute->get_variation(), true ); ?> name="attribute_variation[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Used for variations', 'woocommerce' ); ?></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
/**
|
||||
* Hook to display custom attribute terms.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @param WC_Product_Attribute $attribute Attribute object.
|
||||
* @param number $i Attribute index.
|
||||
*/
|
||||
do_action( 'woocommerce_after_product_attribute_settings', $attribute, $i );
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox postbox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
|
||||
<h3>
|
||||
<div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
|
||||
<div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop to set admin attribute order', 'woocommerce' ); ?>"></div>
|
||||
<a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
|
||||
<strong class="attribute_name<?php echo esc_attr( $attribute->get_name() === '' ? ' placeholder' : '' ); ?>"><?php echo esc_html( $attribute->get_name() !== '' ? wc_attribute_label( $attribute->get_name() ) : __( 'New attribute', 'woocommerce' ) ); ?></strong>
|
||||
</h3>
|
||||
<div class="woocommerce_attribute_data wc-metabox-content hidden">
|
||||
<?php require __DIR__ . '/html-product-attribute-inner.php'; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div id="advanced_product_data" class="panel woocommerce_options_panel hidden">
|
||||
|
||||
<div class="options_group hide_if_external hide_if_grouped">
|
||||
<?php
|
||||
woocommerce_wp_textarea_input(
|
||||
array(
|
||||
'id' => '_purchase_note',
|
||||
'value' => $product_object->get_purchase_note( 'edit' ),
|
||||
'label' => __( 'Purchase note', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Enter an optional note to send the customer after purchase.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="options_group">
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => 'menu_order',
|
||||
'value' => $product_object->get_menu_order( 'edit' ),
|
||||
'label' => __( 'Menu order', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Custom ordering position.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => '1',
|
||||
),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php if ( post_type_supports( 'product', 'comments' ) ) : ?>
|
||||
<div class="options_group reviews">
|
||||
<?php
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => 'comment_status',
|
||||
'value' => $product_object->get_reviews_allowed( 'edit' ) ? 'open' : 'closed',
|
||||
'label' => __( 'Enable reviews', 'woocommerce' ),
|
||||
'cbvalue' => 'open',
|
||||
)
|
||||
);
|
||||
do_action( 'woocommerce_product_options_reviews' );
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_product_options_advanced' ); ?>
|
||||
</div>
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays the attributes tab in the product data meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
global $wc_product_attributes;
|
||||
// Array of defined attribute taxonomies.
|
||||
$attribute_taxonomies = wc_get_attribute_taxonomies();
|
||||
// Product attributes - taxonomies and custom, ordered, with visibility and variation attributes set.
|
||||
$product_attributes = $product_object->get_attributes( 'edit' );
|
||||
?>
|
||||
<div id="product_attributes" class="panel wc-metaboxes-wrapper hidden">
|
||||
<div class="toolbar toolbar-top">
|
||||
<div id="message" class="inline notice woocommerce-message is-dismissible">
|
||||
<p class="help">
|
||||
<?php
|
||||
esc_html_e(
|
||||
'Add descriptive pieces of information that customers can use to search for this product on your store, such as “Material” or “Brand”.',
|
||||
'woocommerce'
|
||||
);
|
||||
?>
|
||||
<button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php esc_html_e( 'Dismiss this notice.', 'woocommerce' ); ?></span></button>
|
||||
</p>
|
||||
</div>
|
||||
<span class="expand-close">
|
||||
<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
|
||||
</span>
|
||||
<div class="actions">
|
||||
<button type="button" class="button add_custom_attribute"><?php esc_html_e( 'Add new', 'woocommerce' ); ?></button>
|
||||
<select class="wc-attribute-search" data-placeholder="<?php esc_attr_e( 'Add existing', 'woocommerce' ); ?>" data-minimum-input-length="0">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product_attributes wc-metaboxes">
|
||||
<?php
|
||||
$i = -1;
|
||||
|
||||
foreach ( $product_attributes as $attribute ) {
|
||||
$i++;
|
||||
$metabox_class = array();
|
||||
|
||||
if ( $attribute->is_taxonomy() ) {
|
||||
$metabox_class[] = 'taxonomy';
|
||||
$metabox_class[] = $attribute->get_name();
|
||||
}
|
||||
|
||||
include __DIR__ . '/html-product-attribute.php';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="toolbar toolbar-buttons">
|
||||
<span class="expand-close">
|
||||
<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
|
||||
</span>
|
||||
<button type="button" aria-disabled="true" class="button save_attributes button-primary disabled"><?php esc_html_e( 'Save attributes', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_product_options_attributes' ); ?>
|
||||
</div>
|
||||
@@ -1,207 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product general data panel.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
?>
|
||||
<div id="general_product_data" class="panel woocommerce_options_panel">
|
||||
|
||||
<div class="options_group show_if_external">
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_product_url',
|
||||
'value' => is_callable( array( $product_object, 'get_product_url' ) ) ? $product_object->get_product_url( 'edit' ) : '',
|
||||
'label' => __( 'Product URL', 'woocommerce' ),
|
||||
'placeholder' => 'https://',
|
||||
'description' => __( 'Enter the external URL to the product.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_button_text',
|
||||
'value' => is_callable( array( $product_object, 'get_button_text' ) ) ? $product_object->get_button_text( 'edit' ) : '',
|
||||
'label' => __( 'Button text', 'woocommerce' ),
|
||||
'placeholder' => _x( 'Buy product', 'placeholder', 'woocommerce' ),
|
||||
'description' => __( 'This text will be shown on the button linking to the external product.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_external' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="options_group pricing show_if_simple show_if_external hidden">
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_regular_price',
|
||||
'value' => $product_object->get_regular_price( 'edit' ),
|
||||
'label' => __( 'Regular price', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')',
|
||||
'data_type' => 'price',
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_sale_price',
|
||||
'value' => $product_object->get_sale_price( 'edit' ),
|
||||
'data_type' => 'price',
|
||||
'label' => __( 'Sale price', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')',
|
||||
'description' => '<a href="#" class="sale_schedule">' . __( 'Schedule', 'woocommerce' ) . '</a>',
|
||||
)
|
||||
);
|
||||
|
||||
$sale_price_dates_from_timestamp = $product_object->get_date_on_sale_from( 'edit' ) ? $product_object->get_date_on_sale_from( 'edit' )->getOffsetTimestamp() : false;
|
||||
$sale_price_dates_to_timestamp = $product_object->get_date_on_sale_to( 'edit' ) ? $product_object->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() : false;
|
||||
|
||||
$sale_price_dates_from = $sale_price_dates_from_timestamp ? date_i18n( 'Y-m-d', $sale_price_dates_from_timestamp ) : '';
|
||||
$sale_price_dates_to = $sale_price_dates_to_timestamp ? date_i18n( 'Y-m-d', $sale_price_dates_to_timestamp ) : '';
|
||||
|
||||
echo '<p class="form-field sale_price_dates_fields">
|
||||
<label for="_sale_price_dates_from">' . esc_html__( 'Sale price dates', 'woocommerce' ) . '</label>
|
||||
<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . esc_html( _x( 'From…', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
|
||||
<input type="text" class="short" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html( _x( 'To…', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
|
||||
<a href="#" class="description cancel_sale_schedule">' . esc_html__( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will start at 00:00:00 of "From" date and end at 23:59:59 of "To" date.', 'woocommerce' ) ) . '
|
||||
</p>';
|
||||
|
||||
do_action( 'woocommerce_product_options_pricing' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="options_group show_if_downloadable hidden">
|
||||
<div class="form-field downloadable_files">
|
||||
<label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
|
||||
<table class="widefat">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort"> </th>
|
||||
<th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
|
||||
<th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$downloadable_files = $product_object->get_downloads( 'edit' );
|
||||
$disabled_downloads_count = 0;
|
||||
|
||||
if ( $downloadable_files ) {
|
||||
foreach ( $downloadable_files as $key => $file ) {
|
||||
$disabled_download = isset( $file['enabled'] ) && false === $file['enabled'];
|
||||
$disabled_downloads_count += (int) $disabled_download;
|
||||
include __DIR__ . '/html-product-download.php';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<a href="#" class="button insert" data-row="
|
||||
<?php
|
||||
$key = '';
|
||||
$file = array(
|
||||
'file' => '',
|
||||
'name' => '',
|
||||
);
|
||||
$disabled_download = false;
|
||||
ob_start();
|
||||
require __DIR__ . '/html-product-download.php';
|
||||
echo esc_attr( ob_get_clean() );
|
||||
?>
|
||||
"><?php esc_html_e( 'Add File', 'woocommerce' ); ?></a>
|
||||
</th>
|
||||
<th colspan="3">
|
||||
<?php if ( $disabled_downloads_count ) : ?>
|
||||
<span class="disabled">*</span>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: opening link tag, 2: closing link tag. */
|
||||
esc_html__( 'The indicated downloads have been disabled (invalid location or filetype—%1$slearn more%2$s).', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/approved-download-directories" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_download_limit',
|
||||
'value' => -1 === $product_object->get_download_limit( 'edit' ) ? '' : $product_object->get_download_limit( 'edit' ),
|
||||
'label' => __( 'Download limit', 'woocommerce' ),
|
||||
'placeholder' => __( 'Unlimited', 'woocommerce' ),
|
||||
'description' => __( 'Leave blank for unlimited re-downloads.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => '1',
|
||||
'min' => '0',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_download_expiry',
|
||||
'value' => -1 === $product_object->get_download_expiry( 'edit' ) ? '' : $product_object->get_download_expiry( 'edit' ),
|
||||
'label' => __( 'Download expiry', 'woocommerce' ),
|
||||
'placeholder' => __( 'Never', 'woocommerce' ),
|
||||
'description' => __( 'Enter the number of days before a download link expires, or leave blank.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => '1',
|
||||
'min' => '0',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_downloads' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php if ( wc_tax_enabled() ) : ?>
|
||||
<div class="options_group show_if_simple show_if_external show_if_variable">
|
||||
<?php
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => '_tax_status',
|
||||
'value' => $product_object->get_tax_status( 'edit' ),
|
||||
'label' => __( 'Tax status', 'woocommerce' ),
|
||||
'options' => array(
|
||||
'taxable' => __( 'Taxable', 'woocommerce' ),
|
||||
'shipping' => __( 'Shipping only', 'woocommerce' ),
|
||||
'none' => _x( 'None', 'Tax status', 'woocommerce' ),
|
||||
),
|
||||
'desc_tip' => 'true',
|
||||
'description' => __( 'Define whether or not the entire product is taxable, or just the cost of shipping it.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => '_tax_class',
|
||||
'value' => $product_object->get_tax_class( 'edit' ),
|
||||
'label' => __( 'Tax class', 'woocommerce' ),
|
||||
'options' => wc_get_product_tax_class_options(),
|
||||
'desc_tip' => 'true',
|
||||
'description' => __( 'Choose a tax class for this product. Tax classes are used to apply different tax rates specific to certain types of product.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_tax' );
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_product_options_general_product_data' ); ?>
|
||||
</div>
|
||||
@@ -1,181 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays the inventory tab in the product data meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div id="inventory_product_data" class="panel woocommerce_options_panel hidden">
|
||||
<div class="options_group">
|
||||
<?php
|
||||
$info_img_url = WC_ADMIN_IMAGES_FOLDER_URL . '/icons/info.svg';
|
||||
|
||||
if ( wc_product_sku_enabled() ) {
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_sku',
|
||||
'value' => $product_object->get_sku( 'edit' ),
|
||||
'label' => '<abbr title="' . esc_attr__( 'Stock Keeping Unit', 'woocommerce' ) . '">' . esc_html__( 'SKU', 'woocommerce' ) . '</abbr>',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_options_sku' );
|
||||
|
||||
?>
|
||||
<div class="inline notice woocommerce-message show_if_variable">
|
||||
<img class="info-icon" src="<?php echo esc_url( $info_img_url ); ?>" />
|
||||
<p>
|
||||
<?php echo esc_html_e( 'Settings below apply to all variations without manual stock management enabled. ', 'woocommerce' ); ?> <a target="_blank" href="https://woocommerce.com/document/variable-product/"><?php esc_html_e( 'Learn more', 'woocommerce' ); ?></a>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => '_manage_stock',
|
||||
'value' => $product_object->get_manage_stock( 'edit' ) ? 'yes' : 'no',
|
||||
'wrapper_class' => 'show_if_simple show_if_variable',
|
||||
'label' => __( 'Stock management', 'woocommerce' ),
|
||||
'description' => __( 'Track stock quantity for this product', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_stock' );
|
||||
|
||||
echo '<div class="stock_fields show_if_simple show_if_variable">';
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_stock',
|
||||
'value' => wc_stock_amount( $product_object->get_stock_quantity( 'edit' ) ?? 1 ),
|
||||
'label' => __( 'Quantity', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Stock quantity. If this is a variable product this value will be used to control stock for all variations, unless you define stock at variation level.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 'any',
|
||||
),
|
||||
'data_type' => 'stock',
|
||||
)
|
||||
);
|
||||
|
||||
echo '<input type="hidden" name="_original_stock" value="' . esc_attr( wc_stock_amount( $product_object->get_stock_quantity( 'edit' ) ) ) . '" />';
|
||||
|
||||
$backorder_args = array(
|
||||
'id' => '_backorders',
|
||||
'value' => $product_object->get_backorders( 'edit' ),
|
||||
'label' => __( 'Allow backorders?', 'woocommerce' ),
|
||||
'options' => wc_get_product_backorder_options(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Allow 3rd parties to control whether "Allow backorder?" option will use radio buttons or a select.
|
||||
*
|
||||
* @since 7.6.0
|
||||
*
|
||||
* @param bool If false, "Allow backorders?" will be shown as a select. Default: it will use radio buttons.
|
||||
*/
|
||||
if ( apply_filters( 'woocommerce_product_allow_backorder_use_radio', true ) ) {
|
||||
woocommerce_wp_radio( $backorder_args );
|
||||
} else {
|
||||
woocommerce_wp_select( $backorder_args );
|
||||
}
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_low_stock_amount',
|
||||
'value' => $product_object->get_low_stock_amount( 'edit' ),
|
||||
'placeholder' => sprintf(
|
||||
/* translators: %d: Amount of stock left */
|
||||
esc_attr__( 'Store-wide threshold (%d)', 'woocommerce' ),
|
||||
esc_attr( get_option( 'woocommerce_notify_low_stock_amount' ) )
|
||||
),
|
||||
'label' => __( 'Low stock threshold', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'When product stock reaches this amount you will be notified by email. It is possible to define different values for each variation individually. The shop default value can be set in Settings > Products > Inventory.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 'any',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_stock_fields' );
|
||||
|
||||
echo '</div>';
|
||||
} else {
|
||||
|
||||
woocommerce_wp_note(
|
||||
array(
|
||||
'id' => '_manage_stock_disabled',
|
||||
'label' => __( 'Stock management', 'woocommerce' ),
|
||||
'label-aria-label' => __( 'Stock management disabled in store settings', 'woocommerce' ),
|
||||
'message' => sprintf(
|
||||
/* translators: %s: url for store settings */
|
||||
__( 'Disabled in <a href="%s" aria-label="stock management store settings">store settings</a>.', 'woocommerce' ),
|
||||
esc_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' )
|
||||
),
|
||||
'wrapper_class' => 'show_if_simple show_if_variable',
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$stock_status_options = wc_get_product_stock_status_options();
|
||||
$stock_status_count = count( $stock_status_options );
|
||||
$stock_status_args = array(
|
||||
'id' => '_stock_status',
|
||||
'value' => $product_object->get_stock_status( 'edit' ),
|
||||
'wrapper_class' => 'stock_status_field hide_if_variable hide_if_external hide_if_grouped',
|
||||
'label' => __( 'Stock status', 'woocommerce' ),
|
||||
'options' => $stock_status_options,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Allow 3rd parties to control whether the "Stock status" option will use radio buttons or a select.
|
||||
*
|
||||
* @since 7.6.0
|
||||
*
|
||||
* @param bool If false, the "Stock status" will be shown as a select. Default: it will use radio buttons.
|
||||
*/
|
||||
if ( apply_filters( 'woocommerce_product_stock_status_use_radio', $stock_status_count <= 3 && $stock_status_count >= 1 ) ) {
|
||||
woocommerce_wp_radio( $stock_status_args );
|
||||
} else {
|
||||
woocommerce_wp_select( $stock_status_args );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_options_stock_status' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="inventory_sold_individually options_group show_if_simple show_if_variable">
|
||||
<?php
|
||||
woocommerce_wp_checkbox(
|
||||
array(
|
||||
'id' => '_sold_individually',
|
||||
'value' => $product_object->get_sold_individually( 'edit' ) ? 'yes' : 'no',
|
||||
'wrapper_class' => 'show_if_simple show_if_variable',
|
||||
'label' => __( 'Sold individually', 'woocommerce' ),
|
||||
'description' => __( 'Limit purchases to 1 item per order', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
echo wc_help_tip( __( 'Check to let customers to purchase only 1 item in a single order. This is particularly useful for items that have limited quantity, for example art or handmade goods.', 'woocommerce' ) );
|
||||
|
||||
do_action( 'woocommerce_product_options_sold_individually' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_product_options_inventory_product_data' ); ?>
|
||||
</div>
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Linked product options.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
?>
|
||||
<div id="linked_product_data" class="panel woocommerce_options_panel hidden">
|
||||
|
||||
<div class="options_group show_if_grouped">
|
||||
<p class="form-field">
|
||||
<label for="grouped_products"><?php esc_html_e( 'Grouped products', 'woocommerce' ); ?></label>
|
||||
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="grouped_products" name="grouped_products[]" data-sortable="true" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-exclude="<?php echo intval( $post->ID ); ?>">
|
||||
<?php
|
||||
$product_ids = $product_object->is_type( 'grouped' ) ? $product_object->get_children( 'edit' ) : array();
|
||||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( is_object( $product ) ) {
|
||||
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select> <?php echo wc_help_tip( __( 'This lets you choose which products are part of this group.', 'woocommerce' ) ); // WPCS: XSS ok. ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="options_group">
|
||||
<p class="form-field">
|
||||
<label for="upsell_ids"><?php esc_html_e( 'Upsells', 'woocommerce' ); ?></label>
|
||||
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="upsell_ids" name="upsell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
|
||||
<?php
|
||||
$product_ids = $product_object->get_upsell_ids( 'edit' );
|
||||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( is_object( $product ) ) {
|
||||
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select> <?php echo wc_help_tip( __( 'Upsells are products which you recommend instead of the currently viewed product, for example, products that are more profitable or better quality or more expensive.', 'woocommerce' ) ); // WPCS: XSS ok. ?>
|
||||
</p>
|
||||
|
||||
<p class="form-field hide_if_grouped hide_if_external">
|
||||
<label for="crosssell_ids"><?php esc_html_e( 'Cross-sells', 'woocommerce' ); ?></label>
|
||||
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="crosssell_ids" name="crosssell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
|
||||
<?php
|
||||
$product_ids = $product_object->get_cross_sell_ids( 'edit' );
|
||||
|
||||
foreach ( $product_ids as $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
if ( is_object( $product ) ) {
|
||||
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select> <?php echo wc_help_tip( __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) ); // WPCS: XSS ok. ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_product_options_related' ); ?>
|
||||
</div>
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product data meta box.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="panel-wrap product_data">
|
||||
|
||||
<span class="product-data-wrapper type_box hidden"> —
|
||||
<label for="product-type">
|
||||
<select id="product-type" name="product-type">
|
||||
<optgroup label="<?php esc_attr_e( 'Product Type', 'woocommerce' ); ?>">
|
||||
<?php foreach ( wc_get_product_types() as $value => $label ) : ?>
|
||||
<option value="<?php echo esc_attr( $value ); ?>" <?php echo selected( $product_object->get_type(), $value, false ); ?>><?php echo esc_html( $label ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
</select>
|
||||
<span class="woocommerce-product-type-tip"></span>
|
||||
</label>
|
||||
|
||||
<?php
|
||||
foreach ( self::get_product_type_options() as $key => $option ) :
|
||||
if ( metadata_exists( 'post', $post->ID, '_' . $key ) ) {
|
||||
$selected_value = is_callable( array( $product_object, "is_$key" ) ) ? $product_object->{"is_$key"}() : 'yes' === get_post_meta( $post->ID, '_' . $key, true );
|
||||
} else {
|
||||
$selected_value = 'yes' === ( isset( $option['default'] ) ? $option['default'] : 'no' );
|
||||
}
|
||||
?>
|
||||
<label for="<?php echo esc_attr( $option['id'] ); ?>" class="<?php echo esc_attr( $option['wrapper_class'] ); ?> tips" data-tip="<?php echo esc_attr( $option['description'] ); ?>">
|
||||
<?php echo esc_html( $option['label'] ); ?>:
|
||||
<input type="checkbox" name="<?php echo esc_attr( $option['id'] ); ?>" id="<?php echo esc_attr( $option['id'] ); ?>" data-product-type-option-id="<?php echo esc_attr( $option['id'] ); ?>" <?php echo checked( $selected_value, true, false ); ?> />
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</span>
|
||||
|
||||
<ul class="product_data_tabs wc-tabs">
|
||||
<?php foreach ( self::get_product_data_tabs() as $key => $tab ) : ?>
|
||||
<li class="<?php echo esc_attr( $key ); ?>_options <?php echo esc_attr( $key ); ?>_tab <?php echo esc_attr( isset( $tab['class'] ) ? implode( ' ', (array) $tab['class'] ) : '' ); ?>">
|
||||
<a href="#<?php echo esc_attr( $tab['target'] ); ?>"><span><?php echo esc_html( $tab['label'] ); ?></span></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
<?php do_action( 'woocommerce_product_write_panel_tabs' ); ?>
|
||||
</ul>
|
||||
|
||||
<?php
|
||||
self::output_tabs();
|
||||
self::output_variations();
|
||||
do_action( 'woocommerce_product_data_panels' );
|
||||
wc_do_deprecated_action( 'woocommerce_product_write_panels', array(), '2.6', 'Use woocommerce_product_data_panels action instead.' );
|
||||
?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
use Automattic\WooCommerce\Utilities\I18nUtil;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div id="shipping_product_data" class="panel woocommerce_options_panel hidden">
|
||||
<div class="options_group">
|
||||
<?php
|
||||
if ( wc_product_weight_enabled() ) {
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_weight',
|
||||
'value' => $product_object->get_weight( 'edit' ),
|
||||
'label' => sprintf(
|
||||
/* translators: %s: Weight unit */
|
||||
__( 'Weight (%s)', 'woocommerce' ),
|
||||
I18nUtil::get_weight_unit_label( get_option( 'woocommerce_weight_unit', 'kg' ) )
|
||||
),
|
||||
'placeholder' => wc_format_localized_decimal( 0 ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Weight in decimal form', 'woocommerce' ),
|
||||
'type' => 'text',
|
||||
'data_type' => 'decimal',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( wc_product_dimensions_enabled() ) {
|
||||
?>
|
||||
<p class="form-field dimensions_field">
|
||||
<label for="product_length">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: WooCommerce dimension unit */
|
||||
esc_html__( 'Dimensions (%s)', 'woocommerce' ),
|
||||
esc_html( I18nUtil::get_dimensions_unit_label( get_option( 'woocommerce_dimension_unit' ) ) )
|
||||
);
|
||||
?>
|
||||
</label>
|
||||
<span class="wrap">
|
||||
<input id="product_length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="_length" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_length( 'edit' ) ) ); ?>" />
|
||||
<input id="product_width" placeholder="<?php esc_attr_e( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="_width" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_width( 'edit' ) ) ); ?>" />
|
||||
<input id="product_height" placeholder="<?php esc_attr_e( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="_height" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_height( 'edit' ) ) ); ?>" />
|
||||
</span>
|
||||
<?php echo wc_help_tip( __( 'LxWxH in decimal form', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_options_dimensions' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="options_group">
|
||||
<?php
|
||||
$args = array(
|
||||
'taxonomy' => 'product_shipping_class',
|
||||
'hide_empty' => 0,
|
||||
'show_option_none' => __( 'No shipping class', 'woocommerce' ),
|
||||
'name' => 'product_shipping_class',
|
||||
'id' => 'product_shipping_class',
|
||||
'selected' => $product_object->get_shipping_class_id( 'edit' ),
|
||||
'class' => 'select short',
|
||||
'orderby' => 'name',
|
||||
);
|
||||
?>
|
||||
<p class="form-field shipping_class_field">
|
||||
<label for="product_shipping_class"><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label>
|
||||
<?php wp_dropdown_categories( $args ); ?>
|
||||
<?php echo wc_help_tip( __( 'Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce' ) ); ?>
|
||||
</p>
|
||||
<?php
|
||||
|
||||
do_action( 'woocommerce_product_options_shipping' );
|
||||
?>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_product_options_shipping_product_data' ); ?>
|
||||
</div>
|
||||
@@ -1,219 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Product data variations
|
||||
*
|
||||
* @package WooCommerce\Admin\Metaboxes\Views
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$add_attributes_img_url = WC_ADMIN_IMAGES_FOLDER_URL . '/icons/info.svg';
|
||||
$background_img_url = WC_ADMIN_IMAGES_FOLDER_URL . '/product_data/no-variation-background-image.svg';
|
||||
$arrow_img_url = WC_ADMIN_IMAGES_FOLDER_URL . '/product_data/no-variation-arrow.svg';
|
||||
?>
|
||||
<div id="variable_product_options" class="panel wc-metaboxes-wrapper hidden">
|
||||
<div id="variable_product_options_inner">
|
||||
<?php if ( ! isset( $variation_attributes ) || ! is_array( $variation_attributes ) || count( $variation_attributes ) === 0 ) : ?>
|
||||
|
||||
<div class="add-attributes-container">
|
||||
<div class="add-attributes-message">
|
||||
<img src="<?php echo esc_url( $add_attributes_img_url ); ?>" />
|
||||
<p>
|
||||
<?php
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
/* translators: %1$s: url for attributes tab, %2$s: url for variable product documentation */
|
||||
__( 'Add some attributes in the <a class="variations-add-attributes-link" href="%1$s">Attributes</a> tab to generate variations. Make sure to check the <b>Used for variations</b> box. <a class="variations-learn-more-link" href="%2$s" target="_blank" rel="noreferrer">Learn more</a>', 'woocommerce' ),
|
||||
esc_url( '#product_attributes' ),
|
||||
esc_url( 'https://woocommerce.com/document/variable-product/' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else : ?>
|
||||
|
||||
<div class="toolbar toolbar-variations-defaults">
|
||||
<div class="variations-defaults">
|
||||
<strong><?php esc_html_e( 'Default Form Values', 'woocommerce' ); ?>: <?php echo wc_help_tip( __( 'Choose a default form value if you want a certain variation already selected when a user visits the product page.', 'woocommerce' ) ); ?></strong>
|
||||
<?php
|
||||
foreach ( $variation_attributes as $attribute ) {
|
||||
$selected_value = isset( $default_attributes[ sanitize_title( $attribute->get_name() ) ] ) ? $default_attributes[ sanitize_title( $attribute->get_name() ) ] : '';
|
||||
?>
|
||||
<select name="default_attribute_<?php echo esc_attr( sanitize_title( $attribute->get_name() ) ); ?>" data-current="<?php echo esc_attr( $selected_value ); ?>">
|
||||
<?php /* translators: WooCommerce attribute label */ ?>
|
||||
<option value=""><?php echo esc_html( sprintf( __( 'No default %s…', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ) ); ?></option>
|
||||
<?php if ( $attribute->is_taxonomy() ) : ?>
|
||||
<?php foreach ( $attribute->get_terms() as $option ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option <?php selected( $selected_value, $option->slug ); ?> value="<?php echo esc_attr( $option->slug ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option->name, $option, $attribute->get_name(), $product_object ) ); ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $attribute->get_options() as $option ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option <?php selected( $selected_value, $option ); ?> value="<?php echo esc_attr( $option ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option, null, $attribute->get_name(), $product_object ) ); ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<?php do_action( 'woocommerce_variable_product_before_variations' ); ?>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
|
||||
<div class="toolbar toolbar-top">
|
||||
<button type="button" class="button generate_variations"><?php esc_html_e( 'Generate variations', 'woocommerce' ); ?></button>
|
||||
<button type="button" class="button add_variation_manually"><?php esc_html_e( 'Add manually', 'woocommerce' ); ?></button>
|
||||
<select id="field_to_edit" class="select variation_actions hidden">
|
||||
<option value="bulk_actions" disabled>Bulk actions</option>
|
||||
<option value="delete_all"><?php esc_html_e( 'Delete all variations', 'woocommerce' ); ?></option>
|
||||
<optgroup label="<?php esc_attr_e( 'Status', 'woocommerce' ); ?>">
|
||||
<option value="toggle_enabled"><?php esc_html_e( 'Toggle "Enabled"', 'woocommerce' ); ?></option>
|
||||
<option value="toggle_downloadable"><?php esc_html_e( 'Toggle "Downloadable"', 'woocommerce' ); ?></option>
|
||||
<option value="toggle_virtual"><?php esc_html_e( 'Toggle "Virtual"', 'woocommerce' ); ?></option>
|
||||
</optgroup>
|
||||
<optgroup label="<?php esc_attr_e( 'Pricing', 'woocommerce' ); ?>">
|
||||
<option value="variable_regular_price"><?php esc_html_e( 'Set regular prices', 'woocommerce' ); ?></option>
|
||||
<option value="variable_regular_price_increase"><?php esc_html_e( 'Increase regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
|
||||
<option value="variable_regular_price_decrease"><?php esc_html_e( 'Decrease regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
|
||||
<option value="variable_sale_price"><?php esc_html_e( 'Set sale prices', 'woocommerce' ); ?></option>
|
||||
<option value="variable_sale_price_increase"><?php esc_html_e( 'Increase sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
|
||||
<option value="variable_sale_price_decrease"><?php esc_html_e( 'Decrease sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
|
||||
<option value="variable_sale_schedule"><?php esc_html_e( 'Set scheduled sale dates', 'woocommerce' ); ?></option>
|
||||
</optgroup>
|
||||
<optgroup label="<?php esc_attr_e( 'Inventory', 'woocommerce' ); ?>">
|
||||
<option value="toggle_manage_stock"><?php esc_html_e( 'Toggle "Manage stock"', 'woocommerce' ); ?></option>
|
||||
<option value="variable_stock"><?php esc_html_e( 'Stock', 'woocommerce' ); ?></option>
|
||||
<option value="variable_stock_status_instock"><?php esc_html_e( 'Set Status - In stock', 'woocommerce' ); ?></option>
|
||||
<option value="variable_stock_status_outofstock"><?php esc_html_e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
|
||||
<option value="variable_stock_status_onbackorder"><?php esc_html_e( 'Set Status - On backorder', 'woocommerce' ); ?></option>
|
||||
<option value="variable_low_stock_amount"><?php esc_html_e( 'Low stock threshold', 'woocommerce' ); ?></option>
|
||||
</optgroup>
|
||||
<optgroup label="<?php esc_attr_e( 'Shipping', 'woocommerce' ); ?>">
|
||||
<option value="variable_length"><?php esc_html_e( 'Length', 'woocommerce' ); ?></option>
|
||||
<option value="variable_width"><?php esc_html_e( 'Width', 'woocommerce' ); ?></option>
|
||||
<option value="variable_height"><?php esc_html_e( 'Height', 'woocommerce' ); ?></option>
|
||||
<option value="variable_weight"><?php esc_html_e( 'Weight', 'woocommerce' ); ?></option>
|
||||
</optgroup>
|
||||
<optgroup label="<?php esc_attr_e( 'Downloadable products', 'woocommerce' ); ?>">
|
||||
<option value="variable_download_limit"><?php esc_html_e( 'Download limit', 'woocommerce' ); ?></option>
|
||||
<option value="variable_download_expiry"><?php esc_html_e( 'Download expiry', 'woocommerce' ); ?></option>
|
||||
</optgroup>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<?php do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
</select>
|
||||
|
||||
<div class="variations-pagenav">
|
||||
<?php /* translators: variations count */ ?>
|
||||
<span class="displaying-num"><?php echo esc_html( sprintf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ) ); ?></span>
|
||||
<span class="expand-close">
|
||||
(<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
|
||||
</span>
|
||||
<span class="pagination-links">
|
||||
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">«</a>
|
||||
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">‹</a>
|
||||
<span class="paging-select">
|
||||
<label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
|
||||
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
|
||||
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<?php echo esc_html_x( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo esc_html( $variations_total_pages ); ?></span>
|
||||
</span>
|
||||
<a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">›</a>
|
||||
<a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">»</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div class="add-variation-container">
|
||||
<div class="arrow-image-wrapper">
|
||||
<img src="<?php echo esc_url( $arrow_img_url ); ?>" />
|
||||
</div>
|
||||
<img src="<?php echo esc_url( $background_img_url ); ?>" />
|
||||
<p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'No variations yet. Generate them from all added attributes or add a new variation manually.',
|
||||
'woocommerce'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<div class="woocommerce_variations wc-metaboxes" data-attributes="<?php echo wc_esc_json( wp_json_encode( wc_list_pluck( $variation_attributes, 'get_data' ) ) ); // WPCS: XSS ok. ?>" data-total="<?php echo esc_attr( $variations_count ); ?>" data-total_pages="<?php echo esc_attr( $variations_total_pages ); ?>" data-page="1" data-edited="false"></div>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
|
||||
<div class="toolbar">
|
||||
<button type="button" class="button-primary save-variation-changes" disabled="disabled"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
|
||||
<button type="button" class="button cancel-variation-changes" disabled="disabled"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
|
||||
|
||||
<div class="variations-pagenav">
|
||||
<?php /* translators: variations count*/ ?>
|
||||
<span class="displaying-num"><?php echo esc_html( sprintf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ) ); ?></span>
|
||||
<span class="expand-close">
|
||||
(<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
|
||||
</span>
|
||||
<span class="pagination-links">
|
||||
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">«</a>
|
||||
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">‹</a>
|
||||
<span class="paging-select">
|
||||
<label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
|
||||
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
|
||||
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<?php echo esc_html_x( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo esc_html( $variations_total_pages ); ?></span>
|
||||
</span>
|
||||
<a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">›</a>
|
||||
<a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">»</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/template" id="tmpl-wc-modal-set-price-variations">
|
||||
<div class="wc-backbone-modal">
|
||||
<div class="wc-backbone-modal-content">
|
||||
<div class="components-modal__content woocommerce-set-price-variations" role="document">
|
||||
<div class="components-modal__header">
|
||||
<h2><?php echo esc_attr( $modal_title ); ?></h2>
|
||||
</div>
|
||||
<div class="woocommerce-usage-modal__wrapper">
|
||||
<div class="woocommerce-usage-modal__message">
|
||||
<span><?php esc_html_e( 'Add price to all variations that don\'t have a price', 'woocommerce' ); ?> (<?php echo esc_attr( get_woocommerce_currency_symbol() ); ?> <?php echo esc_textarea( get_woocommerce_currency() ); ?>)</span>
|
||||
<input type="text" class="components-text-control__input wc_input_variations_price"/>
|
||||
</div>
|
||||
<div class="woocommerce-usage-modal__actions">
|
||||
<button class="modal-close components-button is-secondary"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
|
||||
<button class="modal-close button components-button add_variations_price_button button-primary" disabled><?php esc_html_e( 'Add prices', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wc-backbone-modal-backdrop modal-close"></div>
|
||||
</script>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Template used to form individual rows within the downloadable files table.
|
||||
*
|
||||
* @package WooCommerce\Admin\Views
|
||||
*
|
||||
* @var bool $disabled_download Indicates if the current downloadable file is disabled.
|
||||
* @var array $file Product download data.
|
||||
* @var string $key Product download key.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="sort"></td>
|
||||
<td class="file_name">
|
||||
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_file_names[]" value="<?php echo esc_attr( $file['name'] ); ?>" />
|
||||
<input type="hidden" name="_wc_file_hashes[]" value="<?php echo esc_attr( $key ); ?>" />
|
||||
</td>
|
||||
<td class="file_url">
|
||||
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" />
|
||||
<?php if ( $disabled_download ) : ?>
|
||||
<span class="disabled">*</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo esc_html__( 'Choose file', 'woocommerce' ); ?></a></td>
|
||||
<td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
|
||||
</tr>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Template used to form individual rows within the downloadable files table for variables.
|
||||
*
|
||||
* @package WooCommerce\Admin\Views
|
||||
*
|
||||
* @var bool $disabled_download Indicates if the current downloadable file is disabled.
|
||||
* @var array $file Product download data.
|
||||
* @var string $key Product download key.
|
||||
* @var int $variation_id Variation ID.
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="file_name">
|
||||
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" />
|
||||
<input type="hidden" name="_wc_variation_file_hashes[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $key ); ?>" />
|
||||
</td>
|
||||
<td class="file_url">
|
||||
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" />
|
||||
<?php if ( $disabled_download ) : ?>
|
||||
<span class="disabled">*</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php esc_html_e( 'Choose file', 'woocommerce' ); ?></a></td>
|
||||
<td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
|
||||
</tr>
|
||||
@@ -1,519 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Outputs a variation for editing.
|
||||
*
|
||||
* @package WooCommerce\Admin
|
||||
* @var int $variation_id
|
||||
* @var WP_POST $variation
|
||||
* @var WC_Product_Variation $variation_object
|
||||
* @var array $variation_data array of variation data @deprecated 4.4.0.
|
||||
*/
|
||||
|
||||
use Automattic\WooCommerce\Utilities\I18nUtil;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
?>
|
||||
<div class="woocommerce_variation wc-metabox closed">
|
||||
<h3>
|
||||
<a href="javascript:void(0)" class="edit_variation edit"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a>
|
||||
<a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
|
||||
<div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop, or click to set admin variation order', 'woocommerce' ); ?>"></div>
|
||||
<strong>#<?php echo esc_html( $variation_id ); ?> </strong>
|
||||
<?php
|
||||
$attribute_values = $variation_object->get_attributes( 'edit' );
|
||||
|
||||
foreach ( $product_object->get_attributes( 'edit' ) as $attribute ) {
|
||||
if ( ! $attribute->get_variation() ) {
|
||||
continue;
|
||||
}
|
||||
$selected_value = isset( $attribute_values[ sanitize_title( $attribute->get_name() ) ] ) ? $attribute_values[ sanitize_title( $attribute->get_name() ) ] : '';
|
||||
?>
|
||||
<select name="attribute_<?php echo esc_attr( sanitize_title( $attribute->get_name() ) . "[{$loop}]" ); ?>">
|
||||
<option value="">
|
||||
<?php
|
||||
/* translators: %s: attribute label */
|
||||
printf( esc_html__( 'Any %s…', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</option>
|
||||
<?php if ( $attribute->is_taxonomy() ) : ?>
|
||||
<?php foreach ( $attribute->get_terms() as $option ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option <?php selected( $selected_value, $option->slug ); ?> value="<?php echo esc_attr( $option->slug ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option->name, $option, $attribute->get_name(), $product_object ) ); ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $attribute->get_options() as $option ) : ?>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<option <?php selected( $selected_value, $option ); ?> value="<?php echo esc_attr( $option ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option, null, $attribute->get_name(), $product_object ) ); ?></option>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<input type="hidden" class="variable_post_id" name="variable_post_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_id ); ?>" />
|
||||
<input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_object->get_menu_order( 'edit' ) ); ?>" />
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Variations header action.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param WP_Post $variation Post data.
|
||||
* @param int $loop Position in the loop.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_header', $variation, $loop );
|
||||
?>
|
||||
</h3>
|
||||
<div class="woocommerce_variable_attributes wc-metabox-content" style="display: none;">
|
||||
<div class="data">
|
||||
<p class="form-row form-row-first upload_image">
|
||||
<a href="#" class="upload_image_button tips <?php echo $variation_object->get_image_id( 'edit' ) ? 'remove' : ''; ?>" data-tip="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>" rel="<?php echo esc_attr( $variation_id ); ?>">
|
||||
<img src="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_url( wp_get_attachment_thumb_url( $variation_object->get_image_id( 'edit' ) ) ) : esc_url( wc_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo esc_attr( $loop ); ?>]" class="upload_image_id" value="<?php echo esc_attr( $variation_object->get_image_id( 'edit' ) ); ?>" />
|
||||
</a>
|
||||
</p>
|
||||
<?php
|
||||
if ( wc_product_sku_enabled() ) {
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_sku{$loop}",
|
||||
'name' => "variable_sku[{$loop}]",
|
||||
'value' => $variation_object->get_sku( 'edit' ),
|
||||
'placeholder' => $variation_object->get_sku(),
|
||||
'label' => '<abbr title="' . esc_attr__( 'Stock Keeping Unit', 'woocommerce' ) . '">' . esc_html__( 'SKU', 'woocommerce' ) . '</abbr>',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ),
|
||||
'wrapper_class' => 'form-row form-row-last',
|
||||
)
|
||||
);
|
||||
}
|
||||
?>
|
||||
<p class="form-row form-row-full options">
|
||||
<label>
|
||||
<?php esc_html_e( 'Enabled', 'woocommerce' ); ?>
|
||||
<input type="checkbox" class="checkbox" name="variable_enabled[<?php echo esc_attr( $loop ); ?>]" <?php checked( in_array( $variation_object->get_status( 'edit' ), array( 'publish', false ), true ), true ); ?> />
|
||||
</label>
|
||||
<label class="tips" data-tip="<?php esc_attr_e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>">
|
||||
<?php esc_html_e( 'Downloadable', 'woocommerce' ); ?>
|
||||
<input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_downloadable( 'edit' ), true ); ?> />
|
||||
</label>
|
||||
<label class="tips" data-tip="<?php esc_attr_e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>">
|
||||
<?php esc_html_e( 'Virtual', 'woocommerce' ); ?>
|
||||
<input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_virtual( 'edit' ), true ); ?> />
|
||||
</label>
|
||||
|
||||
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
|
||||
<label class="tips" data-tip="<?php esc_attr_e( 'Enable this option to enable stock management at variation level', 'woocommerce' ); ?>">
|
||||
<?php esc_html_e( 'Manage stock?', 'woocommerce' ); ?>
|
||||
<input type="checkbox" class="checkbox variable_manage_stock" name="variable_manage_stock[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_manage_stock(), true ); // Use view context so 'parent' is considered. ?> />
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<?php do_action( 'woocommerce_variation_options', $loop, $variation_data, $variation ); ?>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
</p>
|
||||
|
||||
<div class="variable_pricing">
|
||||
<?php
|
||||
$label = sprintf(
|
||||
/* translators: %s: currency symbol */
|
||||
__( 'Regular price (%s)', 'woocommerce' ),
|
||||
get_woocommerce_currency_symbol()
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_regular_price_{$loop}",
|
||||
'name' => "variable_regular_price[{$loop}]",
|
||||
'value' => wc_format_localized_price( $variation_object->get_regular_price( 'edit' ) ),
|
||||
'label' => $label,
|
||||
'data_type' => 'price',
|
||||
'wrapper_class' => 'form-row form-row-first',
|
||||
'placeholder' => __( 'Variation price (required)', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
$label = sprintf(
|
||||
/* translators: %s: currency symbol */
|
||||
__( 'Sale price (%s)', 'woocommerce' ),
|
||||
get_woocommerce_currency_symbol()
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_sale_price{$loop}",
|
||||
'name' => "variable_sale_price[{$loop}]",
|
||||
'value' => wc_format_localized_price( $variation_object->get_sale_price( 'edit' ) ),
|
||||
'data_type' => 'price',
|
||||
'label' => $label . ' <a href="#" class="sale_schedule">' . esc_html__( 'Schedule', 'woocommerce' ) . '</a><a href="#" class="cancel_sale_schedule hidden">' . esc_html__( 'Cancel schedule', 'woocommerce' ) . '</a>',
|
||||
'wrapper_class' => 'form-row form-row-last',
|
||||
)
|
||||
);
|
||||
|
||||
$sale_price_dates_from_timestamp = $variation_object->get_date_on_sale_from( 'edit' ) ? $variation_object->get_date_on_sale_from( 'edit' )->getOffsetTimestamp() : false;
|
||||
$sale_price_dates_to_timestamp = $variation_object->get_date_on_sale_to( 'edit' ) ? $variation_object->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() : false;
|
||||
|
||||
$sale_price_dates_from = $sale_price_dates_from_timestamp ? date_i18n( 'Y-m-d', $sale_price_dates_from_timestamp ) : '';
|
||||
$sale_price_dates_to = $sale_price_dates_to_timestamp ? date_i18n( 'Y-m-d', $sale_price_dates_to_timestamp ) : '';
|
||||
|
||||
/* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */
|
||||
echo '<div class="form-field sale_price_dates_fields hidden">
|
||||
<p class="form-row form-row-first">
|
||||
<label>' . esc_html__( 'Sale start date', 'woocommerce' ) . '</label>
|
||||
<input type="text" class="sale_price_dates_from" name="variable_sale_price_dates_from[' . esc_attr( $loop ) . ']" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . esc_attr_x( 'From…', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
|
||||
</p>
|
||||
<p class="form-row form-row-last">
|
||||
<label>' . esc_html__( 'Sale end date', 'woocommerce' ) . '</label>
|
||||
<input type="text" class="sale_price_dates_to" name="variable_sale_price_dates_to[' . esc_attr( $loop ) . ']" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_attr_x( 'To…', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
|
||||
</p>
|
||||
</div>';
|
||||
/* phpcs: enable */
|
||||
|
||||
/**
|
||||
* Variation options pricing action.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $loop Position in the loop.
|
||||
* @param array $variation_data Variation data.
|
||||
* @param WP_Post $variation Post data.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_options_pricing', $loop, $variation_data, $variation );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
|
||||
<div class="show_if_variation_manage_stock" style="display: none;">
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_stock{$loop}",
|
||||
'name' => "variable_stock[{$loop}]",
|
||||
'value' => wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ),
|
||||
'label' => __( 'Stock quantity', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( "Enter a number to set stock quantity at the variation level. Use a variation's 'Manage stock?' check box above to enable/disable stock management at the variation level.", 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 'any',
|
||||
),
|
||||
'data_type' => 'stock',
|
||||
'wrapper_class' => 'form-row form-row-first',
|
||||
)
|
||||
);
|
||||
|
||||
echo '<input type="hidden" name="variable_original_stock[' . esc_attr( $loop ) . ']" value="' . esc_attr( wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ) ) . '" />';
|
||||
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => "variable_backorders{$loop}",
|
||||
'name' => "variable_backorders[{$loop}]",
|
||||
'value' => $variation_object->get_backorders( 'edit' ),
|
||||
'label' => __( 'Allow backorders?', 'woocommerce' ),
|
||||
'options' => wc_get_product_backorder_options(),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'If managing stock, this controls whether or not backorders are allowed. If enabled, stock quantity can go below 0.', 'woocommerce' ),
|
||||
'wrapper_class' => 'form-row form-row-last',
|
||||
)
|
||||
);
|
||||
|
||||
$low_stock_placeholder = ( $product_object->get_manage_stock() && '' !== $product_object->get_low_stock_amount() )
|
||||
? sprintf(
|
||||
/* translators: %d: Amount of stock left */
|
||||
esc_attr__( 'Parent product\'s threshold (%d)', 'woocommerce' ),
|
||||
esc_attr( $product_object->get_low_stock_amount() )
|
||||
)
|
||||
: sprintf(
|
||||
/* translators: %d: Amount of stock left */
|
||||
esc_attr__( 'Store-wide threshold (%d)', 'woocommerce' ),
|
||||
esc_attr( get_option( 'woocommerce_notify_low_stock_amount' ) )
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_low_stock_amount{$loop}",
|
||||
'name' => "variable_low_stock_amount[{$loop}]",
|
||||
'value' => $variation_object->get_low_stock_amount( 'edit' ),
|
||||
'placeholder' => $low_stock_placeholder,
|
||||
'label' => __( 'Low stock threshold', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'When variation stock reaches this amount you will be notified by email. The default value for all variations can be set in the product Inventory tab. The shop default value can be set in Settings > Products > Inventory.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 'any',
|
||||
),
|
||||
'wrapper_class' => 'form-row',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Variation options inventory action.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $loop Position in the loop.
|
||||
* @param array $variation_data Variation data.
|
||||
* @param WP_Post $variation Post data.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_options_inventory', $loop, $variation_data, $variation );
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div>
|
||||
<?php
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => "variable_stock_status{$loop}",
|
||||
'name' => "variable_stock_status[{$loop}]",
|
||||
'value' => $variation_object->get_stock_status( 'edit' ),
|
||||
'label' => __( 'Stock status', 'woocommerce' ),
|
||||
'options' => wc_get_product_stock_status_options(),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ),
|
||||
'wrapper_class' => 'form-row form-row-full variable_stock_status',
|
||||
)
|
||||
);
|
||||
|
||||
if ( wc_product_weight_enabled() ) {
|
||||
$label = sprintf(
|
||||
/* translators: %s: Weight unit */
|
||||
__( 'Weight (%s)', 'woocommerce' ),
|
||||
I18nUtil::get_weight_unit_label( get_option( 'woocommerce_weight_unit', 'kg' ) )
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_weight{$loop}",
|
||||
'name' => "variable_weight[{$loop}]",
|
||||
'value' => wc_format_localized_decimal( $variation_object->get_weight( 'edit' ) ),
|
||||
'placeholder' => wc_format_localized_decimal( $product_object->get_weight() ),
|
||||
'label' => $label,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Weight in decimal form', 'woocommerce' ),
|
||||
'type' => 'text',
|
||||
'data_type' => 'decimal',
|
||||
'wrapper_class' => 'form-row form-row-first hide_if_variation_virtual',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( wc_product_dimensions_enabled() ) {
|
||||
$parent_length = wc_format_localized_decimal( $product_object->get_length() );
|
||||
$parent_width = wc_format_localized_decimal( $product_object->get_width() );
|
||||
$parent_height = wc_format_localized_decimal( $product_object->get_height() );
|
||||
|
||||
?>
|
||||
<p class="form-field form-row dimensions_field hide_if_variation_virtual form-row-last">
|
||||
<label for="product_length">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s dimension unit */
|
||||
esc_html__( 'Dimensions (L×W×H) (%s)', 'woocommerce' ),
|
||||
esc_html( I18nUtil::get_dimensions_unit_label( get_option( 'woocommerce_dimension_unit' ) ) )
|
||||
);
|
||||
?>
|
||||
</label>
|
||||
<?php echo wc_help_tip( __( 'Length x width x height in decimal form', 'woocommerce' ) ); ?>
|
||||
<span class="wrap">
|
||||
<input id="product_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_length( 'edit' ) ) ); ?>" />
|
||||
<input placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_width[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_width( 'edit' ) ) ); ?>" />
|
||||
<input placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_height[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_height( 'edit' ) ) ); ?>" />
|
||||
</span>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Variation options dimensions action.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $loop Position in the loop.
|
||||
* @param array $variation_data Variation data.
|
||||
* @param WP_Post $variation Post data.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_options_dimensions', $loop, $variation_data, $variation );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="form-row hide_if_variation_virtual form-row-full">
|
||||
<label><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label>
|
||||
<?php
|
||||
wp_dropdown_categories(
|
||||
array(
|
||||
'taxonomy' => 'product_shipping_class',
|
||||
'hide_empty' => 0,
|
||||
'show_option_none' => __( 'Same as parent', 'woocommerce' ),
|
||||
'name' => 'variable_shipping_class[' . $loop . ']',
|
||||
'id' => '',
|
||||
'selected' => $variation_object->get_shipping_class_id( 'edit' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
if ( wc_tax_enabled() ) {
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => "variable_tax_class{$loop}",
|
||||
'name' => "variable_tax_class[{$loop}]",
|
||||
'value' => $variation_object->get_tax_class( 'edit' ),
|
||||
'label' => __( 'Tax class', 'woocommerce' ),
|
||||
'options' => array( 'parent' => __( 'Same as parent', 'woocommerce' ) ) + wc_get_product_tax_class_options(),
|
||||
'desc_tip' => 'true',
|
||||
'description' => __( 'Choose a tax class for this product. Tax classes are used to apply different tax rates specific to certain types of product.', 'woocommerce' ),
|
||||
'wrapper_class' => 'form-row form-row-full',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Variation options tax action.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $loop Position in the loop.
|
||||
* @param array $variation_data Variation data.
|
||||
* @param WP_Post $variation Post data.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_options_tax', $loop, $variation_data, $variation );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div>
|
||||
<?php
|
||||
woocommerce_wp_textarea_input(
|
||||
array(
|
||||
'id' => "variable_description{$loop}",
|
||||
'name' => "variable_description[{$loop}]",
|
||||
'value' => $variation_object->get_description( 'edit' ),
|
||||
'label' => __( 'Description', 'woocommerce' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Enter an optional description for this variation.', 'woocommerce' ),
|
||||
'wrapper_class' => 'form-row form-row-full',
|
||||
)
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<div class="show_if_variation_downloadable" style="display: none;">
|
||||
<div class="form-row form-row-full downloadable_files">
|
||||
<label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
|
||||
<table class="widefat">
|
||||
<thead>
|
||||
<div>
|
||||
<th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
|
||||
<th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
|
||||
<th> </th>
|
||||
</div>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$downloadable_files = $variation_object->get_downloads( 'edit' );
|
||||
$disabled_downloads_count = 0;
|
||||
|
||||
if ( $downloadable_files ) {
|
||||
foreach ( $downloadable_files as $key => $file ) {
|
||||
$disabled_download = isset( $file['enabled'] ) && false === $file['enabled'];
|
||||
$disabled_downloads_count += (int) $disabled_download;
|
||||
include __DIR__ . '/html-product-variation-download.php';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<div>
|
||||
<th colspan="1">
|
||||
<a href="#" class="button insert" data-row="
|
||||
<?php
|
||||
$key = '';
|
||||
$file = array(
|
||||
'file' => '',
|
||||
'name' => '',
|
||||
);
|
||||
$disabled_download = false;
|
||||
ob_start();
|
||||
require __DIR__ . '/html-product-variation-download.php';
|
||||
echo esc_attr( ob_get_clean() );
|
||||
?>
|
||||
"><?php esc_html_e( 'Add file', 'woocommerce' ); ?></a>
|
||||
</th>
|
||||
<th colspan="3">
|
||||
<?php if ( $disabled_downloads_count ) : ?>
|
||||
<span class="disabled">*</span>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: opening link tag, 2: closing link tag. */
|
||||
esc_html__( 'The indicated downloads have been disabled (invalid location or filetype—%1$slearn more%2$s).', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/approved-download-directories" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
</th>
|
||||
</div>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="show_if_variation_downloadable" style="display: none;">
|
||||
<?php
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_download_limit{$loop}",
|
||||
'name' => "variable_download_limit[{$loop}]",
|
||||
'value' => $variation_object->get_download_limit( 'edit' ) < 0 ? '' : $variation_object->get_download_limit( 'edit' ),
|
||||
'label' => __( 'Download limit', 'woocommerce' ),
|
||||
'placeholder' => __( 'Unlimited', 'woocommerce' ),
|
||||
'description' => __( 'Leave blank for unlimited re-downloads.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'desc_tip' => true,
|
||||
'custom_attributes' => array(
|
||||
'step' => '1',
|
||||
'min' => '0',
|
||||
),
|
||||
'wrapper_class' => 'form-row form-row-first',
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => "variable_download_expiry{$loop}",
|
||||
'name' => "variable_download_expiry[{$loop}]",
|
||||
'value' => $variation_object->get_download_expiry( 'edit' ) < 0 ? '' : $variation_object->get_download_expiry( 'edit' ),
|
||||
'label' => __( 'Download expiry', 'woocommerce' ),
|
||||
'placeholder' => __( 'Never', 'woocommerce' ),
|
||||
'description' => __( 'Enter the number of days before a download link expires, or leave blank.', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'desc_tip' => true,
|
||||
'custom_attributes' => array(
|
||||
'step' => '1',
|
||||
'min' => '0',
|
||||
),
|
||||
'wrapper_class' => 'form-row form-row-last',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Variation options download action.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $loop Position in the loop.
|
||||
* @param array $variation_data Variation data.
|
||||
* @param WP_Post $variation Post data.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_options_download', $loop, $variation_data, $variation );
|
||||
?>
|
||||
</div>
|
||||
<?php /* phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment */ ?>
|
||||
<?php do_action( 'woocommerce_product_after_variable_attributes', $loop, $variation_data, $variation ); ?>
|
||||
<?php /* phpcs:enable */ ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user