Last active
May 22, 2019 03:27
-
-
Save wpmudev-sls/05b12d73bb9f95e2a5037c9675a49c76 to your computer and use it in GitHub Desktop.
[MarketPress] - Duplicate Products
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: [MarketPress] - Duplicate Products | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: Ability to duplicate products | |
* Author: Panos Lyrakis @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( ! class_exists( 'WPMUDEV_MP_Dulicate_Product' ) ) { | |
class WPMUDEV_MP_Dulicate_Product { | |
private static $_instance = null; | |
public static function get_instance() { | |
if( is_null( self::$_instance ) ) { | |
self::$_instance = new WPMUDEV_MP_Dulicate_Product(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
add_filter( 'post_row_actions', array( $this, 'product_row_action' ), 10, 2 ); | |
add_action( 'admin_footer', array( $this, 'enqueue_scripts' ), 10 ); | |
add_action( 'wp_ajax_wpmudev_mp_duplicate_product', array( $this, 'ajax_duplicate_product' ), 10 ); | |
} | |
public function product_row_action( $actions, $post ){ | |
if ( $post->post_type == "product" ) { | |
if ( 'trash' != $post->post_status && current_user_can( 'edit_products' ) ) { | |
// create a nonce | |
$duplicate_nonce = wp_create_nonce( 'duplicate_product' ); | |
$actions['duplicate'] = sprintf( '<a data-nonce="%s" href="#" data-id="%s" data-title="%s" class="duplicate-product-link">%s</a>', $duplicate_nonce, $post->ID, $post->post_title, __( 'Duplicate product', 'mp' ) ); | |
} | |
} | |
return $actions; | |
} | |
public function enqueue_scripts(){ | |
$screen = get_current_screen(); | |
global $pagenow; | |
if ( 'edit.php' != $pagenow || 'edit-product' != $screen->id ) { | |
return; | |
} | |
?> | |
<script type="text/javascript"> | |
(function($){ | |
$(document).ready(function(){ | |
$( '.duplicate-product-link' ).on( 'click', function( e ) { | |
e.stopImmediatePropagation(); | |
e.preventDefault(); | |
let data, | |
product_info = $( this ), | |
product_id = product_info.data( 'id' ), | |
product_title = product_info.data( 'title' ) | |
confirmation_msg = 'You are about to create a duplicate of product "' + product_title + '".\nAre you sure you want to continue?', | |
notifications_area = $('<div/>', { | |
'class' : 'update-nag duplicate-process-msg', | |
text : 'Product is being duplicated... Please hold on until process is completed' | |
}); | |
$( '#wpbody-content' ).prepend( notifications_area ); | |
if ( window.confirm( confirmation_msg ) ) { | |
data = { | |
action: 'wpmudev_mp_duplicate_product', | |
nonce: product_info.data( 'nonce' ), | |
product_id: product_id | |
}; | |
$.post(ajaxurl, data, function(response) { | |
if( response.success ){ | |
let success_msg = $('<div/>', { | |
'class' : 'duplicate-success-msg', | |
text : 'Product duplicated... Reloading page' | |
}); | |
notifications_area.html( success_msg ); | |
window.location.reload(true); | |
} | |
else{ | |
alert( 'Error in duplicating' ); | |
} | |
}); | |
} | |
}); | |
}); | |
})(jQuery); | |
</script> | |
<?php | |
} | |
public function ajax_duplicate_product(){ | |
check_ajax_referer( 'duplicate_product', 'nonce' ); | |
// SmartCrawl analysis may result in memory exhaustion | |
if ( class_exists( 'Smartcrawl_Controller_Analysis' ) && Smartcrawl_Controller_Analysis::get()->is_running() ){ | |
Smartcrawl_Controller_Analysis::stop(); | |
} | |
$data = $_POST; | |
if( ! isset( $data['product_id'] ) ){ | |
wp_send_json( | |
array( | |
'success' => false, | |
'message' => 'No product selected' | |
) | |
); | |
} | |
$product_id = intval( $data['product_id'] ); | |
$product = new MP_Product( $product_id ); | |
$new_product_id = self::duplicate_product( $product_id ); | |
if( ! $new_product_id ){ | |
wp_send_json( | |
array( | |
'success' => false, | |
'message' => 'Something went wrong' | |
) | |
); | |
} | |
if ( $product->has_variations() ) { | |
$variations = $product->get_variations(); | |
foreach( $variations as $variation ){ | |
$new_variation_id = self::duplicate_product( $variation->ID, $new_product_id ); | |
} | |
} | |
$return = array( | |
'success' => true, | |
); | |
wp_send_json($return); | |
} | |
public static function duplicate_product( $product_id, $parent_id = null ){ | |
global $wpdb; | |
$product = get_post( $product_id ); | |
$product_meta = get_post_meta( $product_id ); | |
$current_user = wp_get_current_user(); | |
$new_post_author = $current_user->ID; | |
$status = is_null( $parent_id ) ? 'draft' : 'publish'; | |
$parent_id = is_null( $parent_id ) ? 0 : $parent_id; | |
if ( isset( $product ) && ! is_null( $product ) ) { | |
$args = array( | |
'comment_status' => $product->comment_status, | |
'ping_status' => $product->ping_status, | |
'post_author' => $new_post_author, | |
'post_content' => $product->post_content, | |
'post_excerpt' => $product->post_excerpt, | |
//'post_name' => $product->post_name, | |
'post_parent' => $parent_id, | |
'post_password' => $product->post_password, | |
'post_status' => $status, | |
'post_title' => $product->post_title . ' Copy', | |
'post_type' => $product->post_type, | |
'to_ping' => $product->to_ping, | |
'menu_order' => $product->menu_order | |
); | |
/* | |
* Insert the new Product | |
*/ | |
$new_product_id = wp_insert_post( $args ); | |
$taxonomies = get_object_taxonomies( MP_Product::get_post_type() ); // returns array of taxonomy names for product CPT. The CPT mp_product_variation wil use terms from these taxonomies | |
foreach ($taxonomies as $taxonomy) { | |
$product_terms = wp_get_object_terms( $product_id, $taxonomy, array('fields' => 'slugs') ); | |
wp_set_object_terms( $new_product_id, $product_terms, $taxonomy, false ); | |
} | |
/* | |
* Duplicate Product meta. Quicker with a single ISNERT query | |
*/ | |
$product_meta = get_post_meta( $product_id ); | |
$sql_insert_values = array(); | |
$exclude_meta_fields = apply_filters( ' | |
WPMUDEV_MP_Dulicate_Product/exclude_meta_fields', | |
array( | |
'eab_event_id', // For Events + Integration, lets not copy the `eab_event_id` meta field, | |
'_wds_analysis', // Should be recalculated | |
'_wds_readability', | |
'_wds_twitter', | |
'_jetpack_related_posts_cache' | |
) | |
); | |
foreach( $product_meta as $meta_key => $meta_value ){ | |
if ( in_array( $meta_key, $exclude_meta_fields ) ) { | |
continue; | |
} | |
//For "regular_price" lets use update_post_meta so hooks are triggered | |
if( 'regular_price' == $meta_key ){ | |
update_post_meta( $new_product_id, 'regular_price', $meta_value[0] ); | |
continue; | |
} | |
$_meta_value = str_replace( "'", "'", $meta_value[0] ); | |
$sql_insert_values[] = sprintf("(%d,'%s','%s')", $new_product_id, $meta_key, $meta_value[0] ); | |
} | |
if( ! empty( $sql_insert_values ) ){ | |
$sql_query = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) VALUES "; | |
$sql_query .= implode( ', ', $sql_insert_values); | |
$wpdb->query( $sql_query ); | |
} | |
} | |
return $new_product_id; | |
} | |
} | |
add_action( 'plugins_loaded', function(){ | |
$GLOBALS['WPMUDEV_MP_Dulicate_Product'] = WPMUDEV_MP_Dulicate_Product::get_instance(); | |
}, 10 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment