woocommerce/includes/admin/class-wc-admin-duplicate-pr...

220 lines
7.0 KiB
PHP
Raw Normal View History

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
2015-11-03 13:53:50 +00:00
* Duplicate product functionality
*
* @author WooCommerce
* @category Admin
* @package WooCommerce/Admin
2017-03-15 16:36:53 +00:00
* @version 3.0.0
*/
if ( class_exists( 'WC_Admin_Duplicate_Product', false ) ) {
return new WC_Admin_Duplicate_Product();
}
/**
* WC_Admin_Duplicate_Product Class.
*/
class WC_Admin_Duplicate_Product {
/**
* Constructor.
*/
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' ) );
}
/**
* Show the "Duplicate" link in admin products list.
*
* @param array $actions Array of actions.
* @param WP_Post $post Post object.
* @return array
*/
public function dupe_link( $actions, $post ) {
global $the_product;
if ( ! current_user_can( apply_filters( 'woocommerce_duplicate_product_capability', 'manage_woocommerce' ) ) ) {
return $actions;
}
2016-09-07 22:32:24 +00:00
if ( 'product' !== $post->post_type ) {
return $actions;
}
// Add Class to Delete Permanently link in row actions.
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() ) {
$actions['trash'] = sprintf(
'<a href="%s" class="submitdelete trash-product" aria-label="%s">%s</a>',
get_delete_post_link( $the_product->get_id(), '', false ),
/* translators: %s: post title */
esc_attr( sprintf( __( 'Move &#8220;%s&#8221; to the Trash', 'woocommerce' ), $the_product->get_name() ) ),
2017-10-12 02:58:45 +00:00
__( 'Trash', 'woocommerce' )
);
}
$actions['duplicate'] = '<a href="' . wp_nonce_url( admin_url( 'edit.php?post_type=product&action=duplicate_product&amp;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>';
return $actions;
}
/**
* Show the dupe product link in admin.
*/
public function dupe_button() {
global $post;
if ( ! current_user_can( apply_filters( 'woocommerce_duplicate_product_capability', 'manage_woocommerce' ) ) ) {
2013-12-02 11:34:27 +00:00
return;
}
if ( ! is_object( $post ) ) {
return;
}
2016-09-07 22:32:24 +00:00
if ( 'product' !== $post->post_type ) {
return;
}
if ( isset( $_GET['post'] ) ) {
2016-05-15 05:41:52 +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'] );
?>
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>
<?php
}
}
/**
* Duplicate a product action.
*/
public function duplicate_product_action() {
if ( empty( $_REQUEST['post'] ) ) {
wp_die( __( 'No product to duplicate has been supplied!', 'woocommerce' ) );
}
$product_id = isset( $_REQUEST['post'] ) ? absint( $_REQUEST['post'] ) : '';
check_admin_referer( 'woocommerce-duplicate-product_' . $product_id );
$product = wc_get_product( $product_id );
if ( false === $product ) {
2016-10-29 10:16:03 +00:00
/* translators: %s: product id */
wp_die( sprintf( __( 'Product creation failed, could not find original product: %s', 'woocommerce' ), $product_id ) );
}
$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.' );
// 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 ) {
// 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() ) );
$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() ) );
$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' ) ) );
}
$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( '' );
$duplicate->set_rating_counts( 0 );
$duplicate->set_average_rating( 0 );
$duplicate->set_review_count( 0 );
foreach ( $meta_to_exclude as $meta_key ) {
$duplicate->delete_meta_data( $meta_key );
}
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
do_action( 'woocommerce_product_duplicate_before_save', $duplicate, $product );
2017-02-16 11:46:01 +00:00
// Save parent product.
$duplicate->save();
// Duplicate children of a variable product.
if ( ! apply_filters( 'woocommerce_duplicate_product_exclude_children', false, $product ) && $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $child_id ) {
$child = wc_get_product( $child_id );
$child_duplicate = clone $child;
$child_duplicate->set_parent_id( $duplicate->get_id() );
$child_duplicate->set_id( 0 );
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' ) ) );
}
foreach ( $meta_to_exclude as $meta_key ) {
$child_duplicate->delete_meta_data( $meta_key );
}
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
do_action( 'woocommerce_product_duplicate_before_save', $child_duplicate, $child );
$child_duplicate->save();
}
// Get new object to reflect new children.
$duplicate = wc_get_product( $duplicate->get_id() );
}
return $duplicate;
}
/**
* Get a product from the database to duplicate.
*
2017-03-15 16:36:53 +00:00
* @deprecated 3.0.0
* @param mixed $id
* @return object|bool
* @see duplicate_product
*/
private function get_product_to_duplicate( $id ) {
global $wpdb;
$id = absint( $id );
if ( ! $id ) {
return false;
}
2017-02-13 12:58:42 +00:00
$post = $wpdb->get_row( $wpdb->prepare( "SELECT {$wpdb->posts}.* FROM {$wpdb->posts} WHERE ID = %d", $id ) );
if ( isset( $post->post_type ) && 'revision' === $post->post_type ) {
$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 ) );
}
2017-02-13 12:58:42 +00:00
return $post;
}
}
2013-12-02 11:34:27 +00:00
return new WC_Admin_Duplicate_Product();