2013-07-24 16:01:36 +00:00
< ? php
2017-01-24 19:57:48 +00:00
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
2013-07-24 16:01:36 +00:00
/**
2015-11-03 13:53:50 +00:00
* Duplicate product functionality
2013-07-24 16:01:36 +00:00
*
2017-01-24 19:57:48 +00:00
* @ author WooCommerce
2014-11-30 06:52:32 +00:00
* @ category Admin
* @ package WooCommerce / Admin
2017-03-15 16:36:53 +00:00
* @ version 3.0 . 0
2013-07-24 16:01:36 +00:00
*/
2017-11-01 12:43:26 +00:00
if ( class_exists ( 'WC_Admin_Duplicate_Product' , false ) ) {
return new WC_Admin_Duplicate_Product ();
}
2013-07-24 16:01:36 +00:00
/**
2015-11-03 12:28:01 +00:00
* WC_Admin_Duplicate_Product Class .
2013-07-24 16:01:36 +00:00
*/
class WC_Admin_Duplicate_Product {
/**
2015-11-03 12:28:01 +00:00
* Constructor .
2013-07-24 16:01:36 +00:00
*/
public function __construct () {
add_action ( 'admin_action_duplicate_product' , array ( $this , 'duplicate_product_action' ) );
add_filter ( 'post_row_actions' , array ( $this , 'dupe_link' ), 10 , 2 );
add_action ( 'post_submitbox_start' , array ( $this , 'dupe_button' ) );
}
/**
2015-11-03 12:28:01 +00:00
* Show the " Duplicate " link in admin products list .
2017-11-01 12:43:26 +00:00
*
* @ param array $actions Array of actions .
* @ param WP_Post $post Post object .
2013-07-24 16:01:36 +00:00
* @ return array
*/
public function dupe_link ( $actions , $post ) {
2017-11-01 12:43:26 +00:00
global $the_product ;
2014-11-30 06:52:32 +00:00
if ( ! current_user_can ( apply_filters ( 'woocommerce_duplicate_product_capability' , 'manage_woocommerce' ) ) ) {
2013-07-24 16:01:36 +00:00
return $actions ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
2016-09-07 22:32:24 +00:00
if ( 'product' !== $post -> post_type ) {
2013-07-24 16:01:36 +00:00
return $actions ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
2017-10-08 10:03:53 +00:00
// Add Class to Delete Permanently link in row actions.
2017-11-01 12:43:26 +00:00
if ( empty ( $the_product ) || $the_product -> get_id () !== $post -> ID ) {
$the_product = wc_get_product ( $post );
}
if ( 'publish' === $post -> post_status && $the_product && 0 < $the_product -> get_total_sales () ) {
2017-10-09 10:46:22 +00:00
$actions [ 'trash' ] = sprintf (
'<a href="%s" class="submitdelete trash-product" aria-label="%s">%s</a>' ,
2017-11-01 12:43:26 +00:00
get_delete_post_link ( $the_product -> get_id (), '' , false ),
2017-10-08 10:03:53 +00:00
/* translators: %s: post title */
2017-11-01 12:43:26 +00:00
esc_attr ( sprintf ( __ ( 'Move “%s” to the Trash' , 'woocommerce' ), $the_product -> get_name () ) ),
2017-10-12 02:58:45 +00:00
__ ( 'Trash' , 'woocommerce' )
2017-10-08 10:03:53 +00:00
);
}
2016-11-04 15:41:51 +00:00
$actions [ 'duplicate' ] = '<a href="' . wp_nonce_url ( admin_url ( 'edit.php?post_type=product&action=duplicate_product&post=' . $post -> ID ), 'woocommerce-duplicate-product_' . $post -> ID ) . '" aria-label="' . esc_attr__ ( 'Make a duplicate from this product' , 'woocommerce' )
2016-09-01 20:50:14 +00:00
. '" rel="permalink">' . __ ( 'Duplicate' , 'woocommerce' ) . '</a>' ;
2013-07-24 16:01:36 +00:00
return $actions ;
}
/**
2015-11-03 12:28:01 +00:00
* Show the dupe product link in admin .
2013-07-24 16:01:36 +00:00
*/
public function dupe_button () {
global $post ;
2014-11-30 06:52:32 +00:00
if ( ! current_user_can ( apply_filters ( 'woocommerce_duplicate_product_capability' , 'manage_woocommerce' ) ) ) {
2013-12-02 11:34:27 +00:00
return ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
2014-11-30 06:52:32 +00:00
if ( ! is_object ( $post ) ) {
2013-07-24 16:01:36 +00:00
return ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
2016-09-07 22:32:24 +00:00
if ( 'product' !== $post -> post_type ) {
2013-07-24 16:01:36 +00:00
return ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
if ( isset ( $_GET [ 'post' ] ) ) {
2018-03-05 18:59:17 +00:00
$notify_url = wp_nonce_url ( admin_url ( 'edit.php?post_type=product&action=duplicate_product&post=' . absint ( $_GET [ 'post' ] ) ), 'woocommerce-duplicate-product_' . $_GET [ 'post' ] );
2013-07-24 16:01:36 +00:00
?>
2016-05-15 05:41:52 +00:00
< div id = " duplicate-action " >< a class = " submitduplicate duplication " href = " <?php echo esc_url( $notify_url ); ?> " >< ? php _e ( 'Copy to a new draft' , 'woocommerce' ); ?> </a></div>
2013-07-24 16:01:36 +00:00
< ? php
}
}
/**
* Duplicate a product action .
*/
public function duplicate_product_action () {
if ( empty ( $_REQUEST [ 'post' ] ) ) {
2014-11-30 06:52:32 +00:00
wp_die ( __ ( 'No product to duplicate has been supplied!' , 'woocommerce' ) );
2013-07-24 16:01:36 +00:00
}
2017-01-24 19:57:48 +00:00
$product_id = isset ( $_REQUEST [ 'post' ] ) ? absint ( $_REQUEST [ 'post' ] ) : '' ;
2013-07-24 16:01:36 +00:00
2017-01-24 19:57:48 +00:00
check_admin_referer ( 'woocommerce-duplicate-product_' . $product_id );
2013-07-24 16:01:36 +00:00
2017-01-24 19:57:48 +00:00
$product = wc_get_product ( $product_id );
2013-07-24 16:01:36 +00:00
2017-01-24 19:57:48 +00:00
if ( false === $product ) {
2016-10-29 10:16:03 +00:00
/* translators: %s: product id */
2017-01-24 19:57:48 +00:00
wp_die ( sprintf ( __ ( 'Product creation failed, could not find original product: %s' , 'woocommerce' ), $product_id ) );
2013-07-24 16:01:36 +00:00
}
2017-02-18 16:50:45 +00:00
$duplicate = $this -> product_duplicate ( $product );
// Hook rename to match other woocommerce_product_* hooks, and to move away from depending on a response from the wp_posts table.
do_action ( 'woocommerce_product_duplicate' , $duplicate , $product );
2017-03-15 16:36:53 +00:00
wc_do_deprecated_action ( 'woocommerce_duplicate_product' , array ( $duplicate -> get_id (), $this -> get_product_to_duplicate ( $product_id ) ), '3.0' , 'Use woocommerce_product_duplicate action instead.' );
2017-02-18 16:50:45 +00:00
// Redirect to the edit screen for the new draft page
wp_redirect ( admin_url ( 'post.php?action=edit&post=' . $duplicate -> get_id () ) );
exit ;
}
/**
* Function to create the duplicate of the product .
*
* @ param WC_Product $product
* @ return WC_Product
*/
public function product_duplicate ( $product ) {
2017-02-15 15:35:59 +00:00
// Filter to allow us to unset/remove data we don't want to copy to the duplicate. @since 2.6
$meta_to_exclude = array_filter ( apply_filters ( 'woocommerce_duplicate_product_exclude_meta' , array () ) );
2017-01-24 19:57:48 +00:00
$duplicate = clone $product ;
$duplicate -> set_id ( 0 );
2017-04-08 12:59:01 +00:00
$duplicate -> set_name ( sprintf ( __ ( '%s (Copy)' , 'woocommerce' ), $duplicate -> get_name () ) );
2017-02-15 15:35:59 +00:00
$duplicate -> set_total_sales ( 0 );
2017-02-24 11:42:28 +00:00
if ( '' !== $product -> get_sku ( 'edit' ) ) {
$duplicate -> set_sku ( wc_product_generate_unique_sku ( 0 , $product -> get_sku ( 'edit' ) ) );
2017-02-15 15:35:59 +00:00
}
$duplicate -> set_status ( 'draft' );
2017-04-06 21:11:00 +00:00
$duplicate -> set_date_created ( null );
2017-04-08 15:14:34 +00:00
$duplicate -> set_slug ( '' );
2017-04-14 06:07:15 +00:00
$duplicate -> set_rating_counts ( 0 );
$duplicate -> set_average_rating ( 0 );
$duplicate -> set_review_count ( 0 );
2013-07-24 16:01:36 +00:00
2017-02-15 15:35:59 +00:00
foreach ( $meta_to_exclude as $meta_key ) {
$duplicate -> delete_meta_data ( $meta_key );
2017-01-25 19:44:27 +00:00
}
2017-03-15 16:36:53 +00:00
// This action can be used to modify the object further before it is created - it will be passed by reference. @since 3.0
2017-02-15 15:35:59 +00:00
do_action ( 'woocommerce_product_duplicate_before_save' , $duplicate , $product );
2017-02-16 11:46:01 +00:00
2017-02-15 15:35:59 +00:00
// Save parent product.
$duplicate -> save ();
2017-04-10 20:45:57 +00:00
// Duplicate children of a variable product.
2017-06-26 07:04:20 +00:00
if ( ! apply_filters ( 'woocommerce_duplicate_product_exclude_children' , false , $product ) && $product -> is_type ( 'variable' ) ) {
2017-02-15 15:35:59 +00:00
foreach ( $product -> get_children () as $child_id ) {
$child = wc_get_product ( $child_id );
2017-01-24 19:57:48 +00:00
$child_duplicate = clone $child ;
$child_duplicate -> set_parent_id ( $duplicate -> get_id () );
$child_duplicate -> set_id ( 0 );
2018-05-15 14:37:17 +00:00
$child_duplicate -> set_date_created ( null );
2017-02-15 15:35:59 +00:00
2017-02-24 11:42:28 +00:00
if ( '' !== $child -> get_sku ( 'edit' ) ) {
$child_duplicate -> set_sku ( wc_product_generate_unique_sku ( 0 , $child -> get_sku ( 'edit' ) ) );
2017-02-15 15:35:59 +00:00
}
foreach ( $meta_to_exclude as $meta_key ) {
$child_duplicate -> delete_meta_data ( $meta_key );
2017-01-25 19:44:27 +00:00
}
2017-02-15 15:35:59 +00:00
2017-03-15 16:36:53 +00:00
// This action can be used to modify the object further before it is created - it will be passed by reference. @since 3.0
2017-02-15 15:35:59 +00:00
do_action ( 'woocommerce_product_duplicate_before_save' , $child_duplicate , $child );
$child_duplicate -> save ();
2014-11-30 06:52:32 +00:00
}
2017-06-26 11:54:46 +00:00
// Get new object to reflect new children.
$duplicate = wc_get_product ( $duplicate -> get_id () );
2013-07-24 16:01:36 +00:00
}
2017-02-18 16:50:45 +00:00
return $duplicate ;
2013-07-24 16:01:36 +00:00
}
/**
2015-11-03 12:28:01 +00:00
* Get a product from the database to duplicate .
2014-11-30 06:52:32 +00:00
*
2017-03-15 16:36:53 +00:00
* @ deprecated 3.0 . 0
2013-07-24 16:01:36 +00:00
* @ param mixed $id
2017-05-15 11:50:52 +00:00
* @ return object | bool
2013-11-27 09:03:47 +00:00
* @ see duplicate_product
2013-07-24 16:01:36 +00:00
*/
private function get_product_to_duplicate ( $id ) {
global $wpdb ;
$id = absint ( $id );
2014-11-30 06:52:32 +00:00
if ( ! $id ) {
2013-07-24 16:01:36 +00:00
return false ;
2014-11-30 06:52:32 +00:00
}
2013-07-24 16:01:36 +00:00
2017-02-13 12:58:42 +00:00
$post = $wpdb -> get_row ( $wpdb -> prepare ( " SELECT { $wpdb -> posts } .* FROM { $wpdb -> posts } WHERE ID = %d " , $id ) );
2013-07-24 16:01:36 +00:00
2016-07-14 12:54:39 +00:00
if ( isset ( $post -> post_type ) && 'revision' === $post -> post_type ) {
2013-07-24 16:01:36 +00:00
$id = $post -> post_parent ;
2017-02-13 12:58:42 +00:00
$post = $wpdb -> get_row ( $wpdb -> prepare ( " SELECT { $wpdb -> posts } .* FROM { $wpdb -> posts } WHERE ID = %d " , $id ) );
2013-07-24 16:01:36 +00:00
}
2014-11-30 06:52:32 +00:00
2017-02-13 12:58:42 +00:00
return $post ;
2013-07-24 16:01:36 +00:00
}
}
2013-12-02 11:34:27 +00:00
return new WC_Admin_Duplicate_Product ();