Skip to content

Instantly share code, notes, and snippets.

@wpmudev-sls
Last active May 22, 2019 03:27
Show Gist options
  • Save wpmudev-sls/05b12d73bb9f95e2a5037c9675a49c76 to your computer and use it in GitHub Desktop.
Save wpmudev-sls/05b12d73bb9f95e2a5037c9675a49c76 to your computer and use it in GitHub Desktop.
[MarketPress] - Duplicate Products
<?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( "'", "&#039;", $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