khaihihi
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
<?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' ),
|
||||
'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://docs.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 ) . '>' . wp_kses_post( $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 ) . '>' . wp_kses_post( $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' => __( 'Whitelist of 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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Actions
|
||||
*
|
||||
* Functions for displaying the order actions 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_Order_Actions Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Actions {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $theorder;
|
||||
|
||||
// This is used by some callbacks attached to hooks such as woocommerce_order_actions which rely on the global to determine if actions should be displayed for certain orders.
|
||||
if ( ! is_object( $theorder ) ) {
|
||||
$theorder = wc_get_order( $post->ID );
|
||||
}
|
||||
|
||||
$order_actions = apply_filters(
|
||||
'woocommerce_order_actions', array(
|
||||
'send_order_details' => __( 'Email invoice / order details to customer', 'woocommerce' ),
|
||||
'send_order_details_admin' => __( 'Resend new order notification', 'woocommerce' ),
|
||||
'regenerate_download_permissions' => __( 'Regenerate download permissions', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<ul class="order_actions submitbox">
|
||||
|
||||
<?php do_action( 'woocommerce_order_actions_start', $post->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', $post->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( get_delete_post_link( $post->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' === $post->post_status ? esc_attr__( 'Create', 'woocommerce' ) : esc_attr__( 'Update', 'woocommerce' ); ?>"><?php echo 'auto-draft' === $post->post_status ? esc_html__( 'Create', 'woocommerce' ) : esc_html__( 'Update', 'woocommerce' ); ?></button>
|
||||
</li>
|
||||
|
||||
<?php do_action( 'woocommerce_order_actions_end', $post->ID ); ?>
|
||||
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
WC()->mailer()->emails['WC_Email_New_Order']->trigger( $order->get_id(), $order );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Data
|
||||
*
|
||||
* Functions for displaying the order data meta box.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce/Admin/Meta Boxes
|
||||
* @version 2.2.0
|
||||
*/
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* Init billing and shipping fields we display + save.
|
||||
*/
|
||||
public static function init_address_fields() {
|
||||
|
||||
self::$billing_fields = 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', 'woocommerce' ),
|
||||
'show' => false,
|
||||
'class' => 'js_field-country select short',
|
||||
'type' => 'select',
|
||||
'options' => array( '' => __( 'Select a country…', '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' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
self::$shipping_fields = 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', 'woocommerce' ),
|
||||
'show' => false,
|
||||
'type' => 'select',
|
||||
'class' => 'js_field-country select short',
|
||||
'options' => array( '' => __( 'Select a country…', 'woocommerce' ) ) + WC()->countries->get_shipping_countries(),
|
||||
),
|
||||
'state' => array(
|
||||
'label' => __( 'State / County', 'woocommerce' ),
|
||||
'class' => 'js_field-state select short',
|
||||
'show' => false,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $theorder;
|
||||
|
||||
if ( ! is_object( $theorder ) ) {
|
||||
$theorder = wc_get_order( $post->ID );
|
||||
}
|
||||
|
||||
$order = $theorder;
|
||||
|
||||
self::init_address_fields();
|
||||
|
||||
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( $post->post_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 empty( $post->post_title ) ? __( 'Order', 'woocommerce' ) : esc_attr( $post->post_title ); ?>" />
|
||||
<input name="post_status" type="hidden" value="<?php echo esc_attr( $post->post_status ); ?>" />
|
||||
<div id="order_data" class="panel woocommerce-order-data">
|
||||
<h2 class="woocommerce-order-data__heading">
|
||||
<?php
|
||||
|
||||
/* translators: 1: order type 2: order number */
|
||||
printf(
|
||||
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 ) {
|
||||
/* translators: %s: payment method */
|
||||
$payment_method_string = sprintf(
|
||||
__( 'Payment via %s', 'woocommerce' ),
|
||||
esc_html( isset( $payment_gateways[ $payment_method ] ) ? $payment_gateways[ $payment_method ]->get_title() : $payment_method )
|
||||
);
|
||||
|
||||
if ( $transaction_id = $order->get_transaction_id() ) {
|
||||
if ( isset( $payment_gateways[ $payment_method ] ) && ( $url = $payment_gateways[ $payment_method ]->get_transaction_url( $order ) ) ) {
|
||||
$payment_method_string .= ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)';
|
||||
} else {
|
||||
$payment_method_string .= ' (' . esc_html( $transaction_id ) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
$meta_list[] = $payment_method_string;
|
||||
}
|
||||
|
||||
if ( $order->get_date_paid() ) {
|
||||
/* translators: 1: date 2: time */
|
||||
$meta_list[] = sprintf(
|
||||
__( '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' ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $ip_address = $order->get_customer_ip_address() ) {
|
||||
/* translators: %s: IP address */
|
||||
$meta_list[] = sprintf(
|
||||
__( 'Customer IP: %s', 'woocommerce' ),
|
||||
'<span class="woocommerce-Order-customerIP">' . esc_html( $ip_address ) . '</span>'
|
||||
);
|
||||
}
|
||||
|
||||
echo wp_kses_post( implode( '. ', $meta_list ) );
|
||||
|
||||
?>
|
||||
</p>
|
||||
<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">
|
||||
<label for="order_date"><?php _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', strtotime( $post->post_date ) ) ); ?>" 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])' ) ); ?>" />@
|
||||
‎
|
||||
<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', strtotime( $post->post_date ) ) ); ?>" 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', strtotime( $post->post_date ) ) ); ?>" pattern="[0-5]{1}[0-9]{1}" />
|
||||
<input type="hidden" name="order_date_second" value="<?php echo esc_attr( date_i18n( 's', strtotime( $post->post_date ) ) ); ?>" />
|
||||
</p>
|
||||
|
||||
<p class="form-field form-field-wide wc-order-status">
|
||||
<label for="order_status">
|
||||
<?php
|
||||
_e( 'Status:', 'woocommerce' );
|
||||
if ( $order->needs_payment() ) {
|
||||
printf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $order->get_checkout_payment_url() ),
|
||||
__( '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
|
||||
_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' ) ) ),
|
||||
' ' . __( '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' ) ) ),
|
||||
' ' . __( 'Profile →', 'woocommerce' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</label>
|
||||
<?php
|
||||
$user_string = '';
|
||||
$user_id = '';
|
||||
if ( $order->get_user_id() ) {
|
||||
$user_id = absint( $order->get_user_id() );
|
||||
$user = get_user_by( 'id', $user_id );
|
||||
/* translators: 1: user display name 2: user ID 3: user email */
|
||||
$user_string = sprintf(
|
||||
esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ),
|
||||
$user->display_name,
|
||||
absint( $user->ID ),
|
||||
$user->user_email
|
||||
);
|
||||
}
|
||||
?>
|
||||
<select class="wc-customer-search" id="customer_user" name="customer_user" data-placeholder="<?php esc_attr_e( 'Guest', 'woocommerce' ); ?>" data-allow_clear="true">
|
||||
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( wp_kses_post( $user_string ) ); // htmlspecialchars to prevent XSS when rendered by selectWoo. ?></option>
|
||||
</select>
|
||||
<!--/email_off-->
|
||||
</p>
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); ?>
|
||||
</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>' . __( 'Address:', 'woocommerce' ) . '</strong> ' . __( 'No billing address set.', 'woocommerce' ) . '</p>';
|
||||
}
|
||||
|
||||
foreach ( self::$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 );
|
||||
} 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.
|
||||
foreach ( self::$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 );
|
||||
break;
|
||||
default:
|
||||
woocommerce_wp_text_input( $field );
|
||||
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">' . __( 'Other', 'woocommerce' ) . '</option>';
|
||||
} else {
|
||||
echo '<option value="other">' . __( 'Other', 'woocommerce' ) . '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
<?php
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_transaction_id',
|
||||
'label' => __( 'Transaction ID', 'woocommerce' ),
|
||||
'value' => $order->get_transaction_id( 'edit' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_billing_address', $order ); ?>
|
||||
</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>' . __( 'Address:', 'woocommerce' ) . '</strong> ' . __( 'No shipping address set.', 'woocommerce' ) . '</p>';
|
||||
}
|
||||
|
||||
if ( ! empty( self::$shipping_fields ) ) {
|
||||
foreach ( self::$shipping_fields as $key => $field ) {
|
||||
if ( isset( $field['show'] ) && false === $field['show'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field_name = 'shipping_' . $key;
|
||||
|
||||
if ( is_callable( array( $order, 'get_' . $field_name ) ) ) {
|
||||
$field_value = $order->{"get_$field_name"}( 'edit' );
|
||||
} else {
|
||||
$field_value = $order->get_meta( '_' . $field_name );
|
||||
}
|
||||
|
||||
if ( $field_value ) {
|
||||
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' ) ) && $post->post_excerpt ) {
|
||||
echo '<p class="order_note"><strong>' . __( 'Customer provided note:', 'woocommerce' ) . '</strong> ' . nl2br( esc_html( $post->post_excerpt ) ) . '</p>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit_address">
|
||||
<?php
|
||||
|
||||
// Display form.
|
||||
if ( ! empty( self::$shipping_fields ) ) {
|
||||
foreach ( self::$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 ( 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 );
|
||||
break;
|
||||
default:
|
||||
woocommerce_wp_text_input( $field );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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="excerpt"><?php _e( 'Customer provided note', 'woocommerce' ); ?>:</label>
|
||||
<textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt" placeholder="<?php esc_attr_e( 'Customer notes about the order', 'woocommerce' ); ?>"><?php echo wp_kses_post( $post->post_excerpt ); ?></textarea>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_data_after_shipping_address', $order ); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
*/
|
||||
public static function save( $order_id ) {
|
||||
self::init_address_fields();
|
||||
|
||||
// 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.
|
||||
if ( ! empty( self::$billing_fields ) ) {
|
||||
foreach ( self::$billing_fields as $key => $field ) {
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_billing_' . $key;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST[ $field['id'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_callable( array( $order, 'set_billing_' . $key ) ) ) {
|
||||
$props[ 'billing_' . $key ] = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
|
||||
} else {
|
||||
$order->update_meta_data( $field['id'], wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update shipping fields.
|
||||
if ( ! empty( self::$shipping_fields ) ) {
|
||||
foreach ( self::$shipping_fields as $key => $field ) {
|
||||
if ( ! isset( $field['id'] ) ) {
|
||||
$field['id'] = '_shipping_' . $key;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST[ $field['id'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_callable( array( $order, 'set_shipping_' . $key ) ) ) {
|
||||
$props[ 'shipping_' . $key ] = wc_clean( wp_unslash( $_POST[ $field['id'] ] ) );
|
||||
} else {
|
||||
$order->update_meta_data( $field['id'], wc_clean( wp_unslash( $_POST[ $field['id'] ] ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $_POST['_transaction_id'] ) ) {
|
||||
$props['transaction_id'] = wc_clean( wp_unslash( $_POST['_transaction_id'] ) );
|
||||
}
|
||||
|
||||
// Payment method handling.
|
||||
if ( $order->get_payment_method() !== 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();
|
||||
}
|
||||
|
||||
$props['payment_method'] = $payment_method;
|
||||
$props['payment_method_title'] = $payment_method_title;
|
||||
}
|
||||
|
||||
// Update date.
|
||||
if ( empty( $_POST['order_date'] ) ) {
|
||||
$date = current_time( 'timestamp', true );
|
||||
} else {
|
||||
$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'] ) && $_POST['original_post_status'] === 'auto-draft' ) {
|
||||
$props['created_via'] = 'admin';
|
||||
}
|
||||
|
||||
// Save order data.
|
||||
$order->set_props( $props );
|
||||
$order->set_status( wc_clean( wp_unslash( $_POST['order_status'] ) ), '', true );
|
||||
$order->save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Downloads
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @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 WP_Post $post
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
?>
|
||||
<div class="order_download_permissions wc-metaboxes-wrapper">
|
||||
|
||||
<div class="wc-metaboxes">
|
||||
<?php
|
||||
$data_store = WC_Data_Store::load( 'customer-download' );
|
||||
$download_permissions = $data_store->get_downloads(
|
||||
array(
|
||||
'order_id' => $post->ID,
|
||||
'orderby' => 'product_id',
|
||||
)
|
||||
);
|
||||
|
||||
$product = null;
|
||||
$loop = 0;
|
||||
$file_counter = 1;
|
||||
|
||||
if ( $download_permissions && sizeof( $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() );
|
||||
$file_count = isset( $file['name'] ) ? $file['name'] : sprintf( __( 'File %d', 'woocommerce' ), $file_counter );
|
||||
|
||||
include '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 _e( 'Grant access', 'woocommerce' ); ?>
|
||||
</button>
|
||||
</p>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Data
|
||||
*
|
||||
* Functions for displaying the order items 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_Order_Items Class.
|
||||
*/
|
||||
class WC_Meta_Box_Order_Items {
|
||||
|
||||
/**
|
||||
* Output the metabox.
|
||||
*
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $post, $thepostid, $theorder;
|
||||
|
||||
if ( ! is_int( $thepostid ) ) {
|
||||
$thepostid = $post->ID;
|
||||
}
|
||||
|
||||
if ( ! is_object( $theorder ) ) {
|
||||
$theorder = wc_get_order( $thepostid );
|
||||
}
|
||||
|
||||
$order = $theorder;
|
||||
$data = get_post_meta( $post->ID );
|
||||
|
||||
include '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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?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 $post Post object.
|
||||
*/
|
||||
public static function output( $post ) {
|
||||
global $post;
|
||||
|
||||
$args = array(
|
||||
'order_id' => $post->ID,
|
||||
);
|
||||
|
||||
$notes = wc_get_order_notes( $args );
|
||||
|
||||
include '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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,537 @@
|
||||
<?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 'views/html-product-data-panel.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show tab content/settings.
|
||||
*/
|
||||
private static function output_tabs() {
|
||||
global $post, $thepostid, $product_object;
|
||||
|
||||
include 'views/html-product-data-general.php';
|
||||
include 'views/html-product-data-inventory.php';
|
||||
include 'views/html-product-data-shipping.php';
|
||||
include 'views/html-product-data-linked-products.php';
|
||||
include 'views/html-product-data-attributes.php';
|
||||
include 'views/html-product-data-advanced.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of product type options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_product_type_options() {
|
||||
return apply_filters(
|
||||
'product_type_options',
|
||||
array(
|
||||
'virtual' => array(
|
||||
'id' => '_virtual',
|
||||
'wrapper_class' => 'show_if_simple',
|
||||
'label' => __( 'Virtual', 'woocommerce' ),
|
||||
'description' => __( 'Virtual products are intangible and are not shipped.', 'woocommerce' ),
|
||||
'default' => 'no',
|
||||
),
|
||||
'downloadable' => array(
|
||||
'id' => '_downloadable',
|
||||
'wrapper_class' => 'show_if_simple',
|
||||
'label' => __( 'Downloadable', 'woocommerce' ),
|
||||
'description' => __( 'Downloadable products give access to a file upon purchase.', 'woocommerce' ),
|
||||
'default' => 'no',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of tabs to show.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function get_product_data_tabs() {
|
||||
$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( 'variations_tab', 'show_if_variable' ),
|
||||
'priority' => 60,
|
||||
),
|
||||
'advanced' => array(
|
||||
'label' => __( 'Advanced', 'woocommerce' ),
|
||||
'target' => 'advanced_product_data',
|
||||
'class' => array(),
|
||||
'priority' => 70,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show options for the variable product type.
|
||||
*/
|
||||
public static function output_variations() {
|
||||
global $post, $wpdb, $product_object;
|
||||
|
||||
$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 );
|
||||
|
||||
include '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.NoNonceVerification
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.NoNonceVerification
|
||||
}
|
||||
|
||||
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( $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( wc_sanitize_term_text_based( $options ) ) : wc_sanitize_textarea( $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 ] ) );
|
||||
$attributes[] = apply_filters( 'woocommerce_admin_meta_boxes_prepare_attribute', $attribute, $data, $i );
|
||||
}
|
||||
}
|
||||
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.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
} else {
|
||||
$value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification, 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.NoNonceVerification
|
||||
// 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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
$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'] ) ? wc_clean( 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 );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_process_product_meta_' . $product_type, $post_id );
|
||||
// phpcs:enable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
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() );
|
||||
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
$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,
|
||||
'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 ] ) ? wc_clean( wp_unslash( $_POST['variable_tax_class'][ $i ] ) ) : null,
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( $errors->get_error_message() );
|
||||
}
|
||||
|
||||
$variation->save();
|
||||
|
||||
do_action( 'woocommerce_save_product_variation', $variation_id, $i );
|
||||
}
|
||||
}
|
||||
// phpcs:enable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?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 ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?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 = $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 = $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>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
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',
|
||||
)
|
||||
);
|
||||
?><div class="view">
|
||||
<?php if ( $meta_data = $item->get_formatted_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 = $item->get_formatted_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>
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows an order item
|
||||
*
|
||||
* @package WooCommerce/Admin
|
||||
* @var object $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 '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_total( $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 = $order->get_qty_refunded_for_item( $item_id );
|
||||
|
||||
if ( $refunded_qty ) {
|
||||
echo '<small class="refunded">-' . esc_html( $refunded_qty * -1 ) . '</small>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="edit" style="display: none;">
|
||||
<input type="number" step="<?php echo esc_attr( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo 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( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" 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 = $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 ] : '';
|
||||
|
||||
if ( '' !== $tax_item_subtotal ) {
|
||||
$round_at_subtotal = 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' );
|
||||
$tax_item_total = wc_round_tax_total( $tax_item_total, $round_at_subtotal ? wc_get_rounding_precision() : null );
|
||||
$tax_item_subtotal = wc_round_tax_total( $tax_item_subtotal, $round_at_subtotal ? wc_get_rounding_precision() : null );
|
||||
}
|
||||
?>
|
||||
<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 = $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>
|
||||
@@ -0,0 +1,425 @@
|
||||
<?php
|
||||
/**
|
||||
* Order items HTML for meta box.
|
||||
*
|
||||
* @package WooCommerce/Admin
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
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 '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_shipping_line_items">
|
||||
<?php
|
||||
$shipping_methods = WC()->shipping() ? WC()->shipping()->load_shipping_methods() : array();
|
||||
foreach ( $line_items_shipping as $item_id => $item ) {
|
||||
include 'html-order-shipping.php';
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_shipping', $order->get_id() );
|
||||
?>
|
||||
</tbody>
|
||||
<tbody id="order_fee_line_items">
|
||||
<?php
|
||||
foreach ( $line_items_fee as $item_id => $item ) {
|
||||
include 'html-order-fee.php';
|
||||
}
|
||||
do_action( 'woocommerce_admin_order_items_after_fees', $order->get_id() );
|
||||
?>
|
||||
</tbody>
|
||||
<tbody id="order_refunds">
|
||||
<?php
|
||||
$refunds = $order->get_refunds();
|
||||
|
||||
if ( $refunds ) {
|
||||
foreach ( $refunds as $refund ) {
|
||||
include '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.OverrideProhibited
|
||||
$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">
|
||||
<?php if ( 0 < $order->get_total_discount() ) : ?>
|
||||
<tr>
|
||||
<td class="label"><?php esc_html_e( 'Discount:', 'woocommerce' ); ?></td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
|
||||
</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
|
||||
$refunded = $order->get_total_shipping_refunded();
|
||||
if ( $refunded > 0 ) {
|
||||
echo '<del>' . wp_strip_all_tags( wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ) ) . '</del> <ins>' . wc_price( $order->get_shipping_total() - $refunded, array( 'currency' => $order->get_currency() ) ) . '</ins>'; // WPCS: XSS ok.
|
||||
} else {
|
||||
echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok.
|
||||
}
|
||||
?>
|
||||
</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
|
||||
$refunded = $order->get_total_tax_refunded_by_rate_id( $tax_total->rate_id );
|
||||
if ( $refunded > 0 ) {
|
||||
echo '<del>' . wp_strip_all_tags( $tax_total->formatted_amount ) . '</del> <ins>' . wc_price( WC_Tax::round( $tax_total->amount, wc_get_price_decimals() ) - WC_Tax::round( $refunded, wc_get_price_decimals() ), array( 'currency' => $order->get_currency() ) ) . '</ins>'; // WPCS: XSS ok.
|
||||
} else {
|
||||
echo wp_kses_post( $tax_total->formatted_amount );
|
||||
}
|
||||
?>
|
||||
</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( 'Total', 'woocommerce' ); ?>:</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<?php echo $order->get_formatted_order_total(); // WPCS: XSS ok. ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_total', $order->get_id() ); ?>
|
||||
|
||||
<?php if ( $order->get_total_refunded() ) : ?>
|
||||
<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() ) ); // WPCS: XSS ok. ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_admin_order_totals_after_refunded', $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"', 'woocommerce' ) ); ?> <?php esc_html_e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
|
||||
<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 ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
|
||||
<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() ) ); // WPCS: XSS ok. ?></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() ) ); // WPCS: XSS ok. ?></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; // WPCS: XSS ok. ?>
|
||||
</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 ) . '">' . WC_Tax::get_rate_label( $rate ) . '</label></td>
|
||||
<td>' . ( isset( $classes_options[ $rate->tax_rate_class ] ) ? $classes_options[ $rate->tax_rate_class ] : '-' ) . '</td>
|
||||
<td>' . WC_Tax::get_rate_code( $rate ) . '</td>
|
||||
<td>' . WC_Tax::get_rate_percent( $rate ) . '</td>
|
||||
</tr>
|
||||
'; // WPCS: XSS ok.
|
||||
}
|
||||
?>
|
||||
</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>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?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><?php esc_html_e( 'There are no notes yet.', 'woocommerce' ); ?></li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* Shows a shipping line
|
||||
*
|
||||
* @var object $item The item being displayed
|
||||
* @var int $item_id The id of the item being displayed
|
||||
*/
|
||||
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 ) {
|
||||
$current_method = ( 0 === strpos( $item->get_method_id(), $method->id ) ) ? $item->get_method_id() : $method->id;
|
||||
|
||||
echo '<option value="' . esc_attr( $current_method ) . '" ' . selected( $item->get_method_id() === $current_method, true, false ) . '>' . esc_html( $method->get_method_title() ) . '</option>';
|
||||
|
||||
if ( $item->get_method_id() === $current_method ) {
|
||||
$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 '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 wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );
|
||||
$refunded = $order->get_total_refunded_for_item( $item_id, 'shipping' );
|
||||
if ( $refunded ) {
|
||||
echo '<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
|
||||
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() ) ) : '–';
|
||||
$refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' );
|
||||
if ( $refunded ) {
|
||||
echo '<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>
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
|
||||
<h3>
|
||||
<a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
|
||||
<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>
|
||||
<strong class="attribute_name"><?php echo wc_attribute_label( $attribute->get_name() ); ?></strong>
|
||||
</h3>
|
||||
<div class="woocommerce_attribute_data wc-metabox-content hidden">
|
||||
<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 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() ); ?>" />
|
||||
<?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_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 ) {
|
||||
?>
|
||||
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo esc_attr( $i ); ?>][]">
|
||||
<?php
|
||||
$args = array(
|
||||
'orderby' => ! empty( $attribute_taxonomy->attribute_orderby ) ? $attribute_taxonomy->attribute_orderby : 'name',
|
||||
'hide_empty' => 0,
|
||||
);
|
||||
$all_terms = get_terms( $attribute->get_taxonomy(), apply_filters( 'woocommerce_product_attribute_terms', $args ) );
|
||||
if ( $all_terms ) {
|
||||
foreach ( $all_terms as $term ) {
|
||||
$options = $attribute->get_options();
|
||||
$options = ! empty( $options ) ? $options : array();
|
||||
echo '<option value="' . esc_attr( $term->term_id ) . '"' . wc_selected( $term->term_id, $options ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $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( 'Add new', 'woocommerce' ); ?></button>
|
||||
<?php
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_option_terms', $attribute_taxonomy, $i, $attribute );
|
||||
} else {
|
||||
/* translators: %s: WC_DELIMITER */
|
||||
?>
|
||||
<textarea name="attribute_values[<?php echo esc_attr( $i ); ?>]" cols="5" rows="5" placeholder="<?php printf( esc_attr__( 'Enter some text, or some attributes by "%s" separating values.', 'woocommerce' ), WC_DELIMITER ); ?>"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label><input type="checkbox" class="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="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 do_action( 'woocommerce_after_product_attribute_settings', $attribute, $i ); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div id="product_attributes" class="panel wc-metaboxes-wrapper hidden">
|
||||
<div class="toolbar toolbar-top">
|
||||
<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>
|
||||
<select name="attribute_taxonomy" class="attribute_taxonomy">
|
||||
<option value=""><?php esc_html_e( 'Custom product attribute', 'woocommerce' ); ?></option>
|
||||
<?php
|
||||
global $wc_product_attributes;
|
||||
|
||||
// Array of defined attribute taxonomies.
|
||||
$attribute_taxonomies = wc_get_attribute_taxonomies();
|
||||
|
||||
if ( ! empty( $attribute_taxonomies ) ) {
|
||||
foreach ( $attribute_taxonomies as $tax ) {
|
||||
$attribute_taxonomy_name = wc_attribute_taxonomy_name( $tax->attribute_name );
|
||||
$label = $tax->attribute_label ? $tax->attribute_label : $tax->attribute_name;
|
||||
echo '<option value="' . esc_attr( $attribute_taxonomy_name ) . '">' . esc_html( $label ) . '</option>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button type="button" class="button add_attribute"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
<div class="product_attributes wc-metaboxes">
|
||||
<?php
|
||||
// Product attributes - taxonomies and custom, ordered, with visibility and variation attributes set.
|
||||
$attributes = $product_object->get_attributes( 'edit' );
|
||||
$i = -1;
|
||||
|
||||
foreach ( $attributes as $attribute ) {
|
||||
$i++;
|
||||
$metabox_class = array();
|
||||
|
||||
if ( $attribute->is_taxonomy() ) {
|
||||
$metabox_class[] = 'taxonomy';
|
||||
$metabox_class[] = $attribute->get_name();
|
||||
}
|
||||
|
||||
include 'html-product-attribute.php';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<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" class="button save_attributes button-primary"><?php esc_html_e( 'Save attributes', 'woocommerce' ); ?></button>
|
||||
</div>
|
||||
<?php do_action( 'woocommerce_product_options_attributes' ); ?>
|
||||
</div>
|
||||
@@ -0,0 +1,187 @@
|
||||
<?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' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</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' );
|
||||
if ( $downloadable_files ) {
|
||||
foreach ( $downloadable_files as $key => $file ) {
|
||||
include 'html-product-download.php';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="5">
|
||||
<a href="#" class="button insert" data-row="
|
||||
<?php
|
||||
$key = '';
|
||||
$file = array(
|
||||
'file' => '',
|
||||
'name' => '',
|
||||
);
|
||||
ob_start();
|
||||
require 'html-product-download.php';
|
||||
echo esc_attr( ob_get_clean() );
|
||||
?>
|
||||
"><?php esc_html_e( 'Add File', 'woocommerce' ); ?></a>
|
||||
</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>
|
||||
@@ -0,0 +1,127 @@
|
||||
<?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
|
||||
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' );
|
||||
|
||||
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' => __( 'Manage stock?', 'woocommerce' ),
|
||||
'description' => __( 'Enable stock management at product level', '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' ) ),
|
||||
'label' => __( 'Stock 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' ) ) ) . '" />';
|
||||
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => '_backorders',
|
||||
'value' => $product_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' ),
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_text_input(
|
||||
array(
|
||||
'id' => '_low_stock_amount',
|
||||
'value' => $product_object->get_low_stock_amount( 'edit' ),
|
||||
'placeholder' => 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', 'woocommerce' ),
|
||||
'type' => 'number',
|
||||
'custom_attributes' => array(
|
||||
'step' => 'any',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_stock_fields' );
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
woocommerce_wp_select(
|
||||
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' => 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' ),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_stock_status' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="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' => __( 'Enable this to only allow one of this item to be bought in a single order', 'woocommerce' ),
|
||||
)
|
||||
);
|
||||
|
||||
do_action( 'woocommerce_product_options_sold_individually' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_product_options_inventory_product_data' ); ?>
|
||||
</div>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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 ) . '>' . wp_kses_post( $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 ) . '>' . wp_kses_post( $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 ) . '>' . wp_kses_post( $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>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Product data meta box.
|
||||
*
|
||||
* @package WooCommerce/Admin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="panel-wrap product_data">
|
||||
|
||||
<span class="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>
|
||||
</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'] ); ?>" <?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>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
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' => __( 'Weight', 'woocommerce' ) . ' (' . get_option( 'woocommerce_weight_unit' ) . ')',
|
||||
'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">
|
||||
<?php /* translators: WooCommerce dimension unit*/ ?>
|
||||
<label for="product_length"><?php printf( __( 'Dimensions (%s)', 'woocommerce' ), 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>
|
||||
</div>
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* Product data variations
|
||||
*
|
||||
* @package WooCommerce\Admin\Metaboxes\Views
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<div id="variable_product_options" class="panel wc-metaboxes-wrapper hidden">
|
||||
<div id="variable_product_options_inner">
|
||||
|
||||
<?php if ( ! count( $variation_attributes ) ) : ?>
|
||||
|
||||
<div id="message" class="inline notice woocommerce-message">
|
||||
<p><?php echo wp_kses_post( __( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ) ); ?></p>
|
||||
<p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php esc_html_e( 'Learn more', 'woocommerce' ); ?></a></p>
|
||||
</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( __( 'These are the attributes that will be pre-selected on the frontend.', '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 ) : ?>
|
||||
<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 endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $attribute->get_options() as $option ) : ?>
|
||||
<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 endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_variable_product_before_variations' ); ?>
|
||||
|
||||
<div class="toolbar toolbar-top">
|
||||
<select id="field_to_edit" class="variation_actions">
|
||||
<option data-global="true" value="add_variation"><?php esc_html_e( 'Add variation', 'woocommerce' ); ?></option>
|
||||
<option data-global="true" value="link_all_variations"><?php esc_html_e( 'Create variations from all attributes', 'woocommerce' ); ?></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>
|
||||
</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 do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?>
|
||||
</select>
|
||||
<a class="button bulk_edit do_variation_action"><?php esc_html_e( 'Go', 'woocommerce' ); ?></a>
|
||||
|
||||
<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++ ) : ?>
|
||||
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
|
||||
<?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="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>
|
||||
|
||||
<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++ ) : ?>
|
||||
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
|
||||
<?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>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
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'] ); ?>" /></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>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
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'] ); ?>" /></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>
|
||||
@@ -0,0 +1,460 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
?>
|
||||
<div class="woocommerce_variation wc-metabox closed">
|
||||
<h3>
|
||||
<a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
|
||||
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
|
||||
<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 ) : ?>
|
||||
<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 endforeach; ?>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $attribute->get_options() as $option ) : ?>
|
||||
<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 endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<input type="hidden" 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.
|
||||
*/
|
||||
do_action( 'woocommerce_variation_header', $variation );
|
||||
?>
|
||||
</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 do_action( 'woocommerce_variation_options', $loop, $variation_data, $variation ); ?>
|
||||
</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 ) : '';
|
||||
|
||||
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>';
|
||||
|
||||
/**
|
||||
* 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',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* 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' ),
|
||||
esc_html( get_option( 'woocommerce_weight_unit' ) )
|
||||
);
|
||||
|
||||
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( 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
|
||||
$downloads = $variation_object->get_downloads( 'edit' );
|
||||
|
||||
if ( $downloads ) {
|
||||
foreach ( $downloads as $key => $file ) {
|
||||
include 'html-product-variation-download.php';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<div>
|
||||
<th colspan="4">
|
||||
<a href="#" class="button insert" data-row="
|
||||
<?php
|
||||
$key = '';
|
||||
$file = array(
|
||||
'file' => '',
|
||||
'name' => '',
|
||||
);
|
||||
ob_start();
|
||||
require 'html-product-variation-download.php';
|
||||
echo esc_attr( ob_get_clean() );
|
||||
?>
|
||||
"><?php esc_html_e( 'Add file', 'woocommerce' ); ?></a>
|
||||
</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 do_action( 'woocommerce_product_after_variable_attributes', $loop, $variation_data, $variation ); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user