1 <?php
2 3 4 5 6 7 8 9
10
11 if ( ! defined( 'ABSPATH' ) ) exit;
12
13 if ( ! class_exists( 'WC_Admin_Duplicate_Product' ) ) :
14
15 16 17
18 class WC_Admin_Duplicate_Product {
19
20 21 22
23 public function __construct() {
24 add_action( 'admin_action_duplicate_product', array( $this, 'duplicate_product_action' ) );
25 add_filter( 'post_row_actions', array( $this, 'dupe_link' ), 10, 2 );
26 add_filter( 'page_row_actions', array( $this, 'dupe_link' ), 10, 2 );
27 add_action( 'post_submitbox_start', array( $this, 'dupe_button' ) );
28 }
29
30 31 32 33 34 35
36 public function dupe_link( $actions, $post ) {
37 if ( ! current_user_can( apply_filters( 'woocommerce_duplicate_product_capability', 'manage_woocommerce' ) ) )
38 return $actions;
39
40 if ( $post->post_type != 'product' )
41 return $actions;
42
43 $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 ) . '" title="' . __( 'Make a duplicate from this product', 'woocommerce' )
44 . '" rel="permalink">' . __( 'Duplicate', 'woocommerce' ) . '</a>';
45
46 return $actions;
47 }
48
49 50 51
52 public function dupe_button() {
53 global $post;
54
55 if ( ! current_user_can( apply_filters( 'woocommerce_duplicate_product_capability', 'manage_woocommerce' ) ) )
56 return;
57
58 if ( ! is_object( $post ) )
59 return;
60
61 if ( $post->post_type != 'product' )
62 return;
63
64 if ( isset( $_GET['post'] ) ) {
65 $notifyUrl = wp_nonce_url( admin_url( "edit.php?post_type=product&action=duplicate_product&post=" . absint( $_GET['post'] ) ), 'woocommerce-duplicate-product_' . $_GET['post'] );
66 ?>
67 <div id="duplicate-action"><a class="submitduplicate duplication" href="<?php echo esc_url( $notifyUrl ); ?>"><?php _e( 'Copy to a new draft', 'woocommerce' ); ?></a></div>
68 <?php
69 }
70 }
71
72 73 74
75 public function duplicate_product_action() {
76 if ( empty( $_REQUEST['post'] ) ) {
77 wp_die(__( 'No product to duplicate has been supplied!', 'woocommerce' ));
78 }
79
80
81 $id = isset( $_REQUEST['post'] ) ? absint( $_REQUEST['post'] ) : '';
82
83 check_admin_referer( 'woocommerce-duplicate-product_' . $id );
84
85 $post = $this->get_product_to_duplicate( $id );
86
87
88 if ( ! empty( $post ) ) {
89 $new_id = $this->duplicate_product( $post );
90
91
92
93 do_action( 'woocommerce_duplicate_product', $new_id, $post );
94
95
96 wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
97 exit;
98 } else {
99 wp_die(__( 'Product creation failed, could not find original product:', 'woocommerce' ) . ' ' . $id );
100 }
101 }
102
103 104 105 106 107 108 109 110 111
112 public function duplicate_product( $post, $parent = 0, $post_status = '' ) {
113 global $wpdb;
114
115 $new_post_author = wp_get_current_user();
116 $new_post_date = current_time('mysql');
117 $new_post_date_gmt = get_gmt_from_date($new_post_date);
118
119 if ( $parent > 0 ) {
120 $post_parent = $parent;
121 $post_status = $post_status ? $post_status : 'publish';
122 $suffix = '';
123 } else {
124 $post_parent = $post->post_parent;
125 $post_status = $post_status ? $post_status : 'draft';
126 $suffix = ' ' . __( '(Copy)', 'woocommerce' );
127 }
128
129 $new_post_type = $post->post_type;
130 $post_content = str_replace("'", "''", $post->post_content);
131 $post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
132 $post_excerpt = str_replace("'", "''", $post->post_excerpt);
133 $post_title = str_replace("'", "''", $post->post_title).$suffix;
134 $post_name = str_replace("'", "''", $post->post_name);
135 $comment_status = str_replace("'", "''", $post->comment_status);
136 $ping_status = str_replace("'", "''", $post->ping_status);
137
138
139 $wpdb->query(
140 "INSERT INTO $wpdb->posts
141 (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
142 VALUES
143 ('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', '$post_status', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post_parent', '$post->menu_order', '$post->post_mime_type')");
144
145 $new_post_id = $wpdb->insert_id;
146
147
148 $this->duplicate_post_taxonomies( $post->ID, $new_post_id, $post->post_type );
149
150
151 $this->duplicate_post_meta( $post->ID, $new_post_id );
152
153
154 if ( $children_products = get_children( 'post_parent='.$post->ID.'&post_type=product_variation' ) ) {
155
156 if ( $children_products )
157 foreach ( $children_products as $child )
158 $this->duplicate_product( $this->get_product_to_duplicate( $child->ID ), $new_post_id, $child->post_status );
159 }
160
161 return $new_post_id;
162 }
163
164 165 166 167 168 169 170 171 172
173 private function get_product_to_duplicate( $id ) {
174 global $wpdb;
175
176 $id = absint( $id );
177
178 if ( ! $id )
179 return false;
180
181 $post = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE ID=$id" );
182
183 if ( isset( $post->post_type ) && $post->post_type == "revision" ) {
184 $id = $post->post_parent;
185 $post = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE ID=$id" );
186 }
187 return $post[0];
188 }
189
190 191 192 193 194 195 196 197 198
199 private function duplicate_post_taxonomies( $id, $new_id, $post_type ) {
200 global $wpdb;
201 $taxonomies = get_object_taxonomies($post_type);
202 foreach ($taxonomies as $taxonomy) {
203 $post_terms = wp_get_object_terms($id, $taxonomy);
204 $post_terms_count = sizeof( $post_terms );
205 for ($i=0; $i<$post_terms_count; $i++) {
206 wp_set_object_terms($new_id, $post_terms[$i]->slug, $taxonomy, true);
207 }
208 }
209 }
210
211 212 213 214 215 216 217 218
219 private function duplicate_post_meta( $id, $new_id ) {
220 global $wpdb;
221 $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$id");
222
223 if (count($post_meta_infos)!=0) {
224 $sql_query_sel = array();
225 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
226 foreach ($post_meta_infos as $meta_info) {
227 $meta_key = $meta_info->meta_key;
228 $meta_value = addslashes($meta_info->meta_value);
229 $sql_query_sel[]= "SELECT $new_id, '$meta_key', '$meta_value'";
230 }
231 $sql_query.= implode(" UNION ALL ", $sql_query_sel);
232 $wpdb->query($sql_query);
233 }
234 }
235
236 }
237
238 endif;
239
240 return new WC_Admin_Duplicate_Product();
241