HEX
Server: LiteSpeed
System: Linux s787.bom1.mysecurecloudhost.com 4.18.0-477.13.1.lve.el8.x86_64 #1 SMP Thu Jun 1 16:40:47 EDT 2023 x86_64
User: mobilech (5348)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: //proc/thread-self/cwd/wp-content/plugins/wp-duplicate-page/includes/Classes/CreateDuplicate.php
<?php
namespace NjtDuplicate\Classes;

defined( 'ABSPATH' ) || exit;
use NjtDuplicate\Helper\Utils;

class CreateDuplicate {
	protected static $instance = null;

	public static function getInstance() {
		if ( null == self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	private function __construct() {

	}

	public function createDuplicate( $post, $parentId = '' ) {

		if ( ! Utils::checkPostTypeDuplicate( $post->post_type ) && 'attachment' !== $post->post_type ) {
			wp_die( esc_html__( 'Copy features for this post type are not enabled in setting page', 'wp-duplicate-page' ) );
		}

		$newPostAuthor   = wp_get_current_user();
		$newPostAuthorId = $newPostAuthor->ID;

		if ( 'attachment' !== $post->post_type ) {

			$title = trim( $post->post_title );
			// empty title
			if ( '' === $title ) {
				$title = __( 'Untitled', 'wp-duplicate-page' );
			}
		} else {
			$title = trim( $post->post_title );
			if ( '' === $title ) {
				$title = __( 'Untitled', 'wp-duplicate-page' );
			}
		}

		$newPost = array(
			'menu_order'            => $post->menu_order,
			'comment_status'        => $post->comment_status,
			'ping_status'           => $post->ping_status,
			'post_author'           => $newPostAuthorId,
			'post_content'          => $post->post_content,
			'post_content_filtered' => $post->post_content_filtered,
			'post_excerpt'          => $post->post_excerpt,
			'post_mime_type'        => $post->post_mime_type,
			'post_parent'           => empty( $parentId ) ? $post->post_parent : $parentId,
			'post_password'         => $post->post_password,
			'post_status'           => 'draft',
			'post_title'            => $title,
			'post_type'             => $post->post_type,
			'post_name'             => $this->generateUniqueSlug( $post->post_name . '-copy', $post->post_type, $post->post_parent ),
			'post_date'             => $post->post_date,
			'post_date_gmt'         => get_gmt_from_date( $post->post_date ),
		);

		$newPostId = wp_insert_post( wp_slash( $newPost ) );

		// Duplicate postmeta, comment, attachment, children, taxonomies,
		if ( 0 !== $newPostId && ! is_wp_error( $newPostId ) ) {
			$this->duplicateDetails( $newPostId, $post );
		}

		return $newPostId;
	}

	private function generateUniqueSlug( string $baseSlug, string $postType, int $postParent ): string {
		$slug   = $baseSlug;
		$suffix = 2;
		$args   = array(
			'name'           => $slug,
			'post_type'      => $postType,
			'post_parent'    => $postParent,
			'post_status'    => 'any',
			'posts_per_page' => 1,
			'fields'         => 'ids',
			'no_found_rows'  => true,
		);
		while ( ! empty( get_posts( $args ) ) ) {
			$slug         = $baseSlug . '-' . $suffix++;
			$args['name'] = $slug;
		}
		return $slug;
	}

	public function createDuplicateOrderHPOS( $originalOrder ) {
		if ( ! Utils::checkPostTypeDuplicate( 'shop_order' ) ) {
			wp_die( esc_html__( 'Copy features for this post type are not enabled in setting page', 'wp-duplicate-page' ) );
		}

		$newDuplicateAuthor   = wp_get_current_user();
		$newDuplicateAuthorId = $newDuplicateAuthor->ID;

		// Disable all WooCommerce order status emails.
		add_filter( 'woocommerce_email_enabled_new_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_cancelled_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_failed_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_customer_on_hold_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_customer_processing_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_customer_completed_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_customer_refunded_order', '__return_false' );
		add_filter( 'woocommerce_email_enabled_customer_invoice', '__return_false' );

		// Temporarily disable stock management.
		add_filter( 'woocommerce_can_reduce_order_stock', '__return_false' );

		$orderData = array(
			'customer_id' => $newDuplicateAuthorId,
			'status'      => 'pending',
			'currency'    => $originalOrder->get_currency(),
			'created_via' => $originalOrder->get_created_via(),
			'billing'     => $originalOrder->get_address( 'billing' ),
			'shipping'    => $originalOrder->get_address( 'shipping' ),
		);

		$order = wc_create_order( $orderData );

		foreach ( $originalOrder->get_meta_data() as $meta ) {
			if ( Utils::excludeMetaKey( $meta->key ) ) {
				continue;
			}
			$order->update_meta_data( $meta->key, $meta->value );
		}

		foreach ( $originalOrder->get_items() as $item ) {
			if ( $item->get_type() === 'line_item' ) {
				$product = $item->get_product();
				if ( $product ) {
					$newItem = new \WC_Order_Item_Product();
					$newItem->set_product_id( $item->get_product_id() );
					$newItem->set_variation_id( $item->get_variation_id() );
					$newItem->set_quantity( $item->get_quantity() );

					// Handle pricing option.
					$newItem->set_subtotal( (string) $item->get_subtotal() );
					$newItem->set_total( (string) $item->get_total() );

					// Copy item meta.
					foreach ( $item->get_meta_data() as $meta ) {
						$newItem->add_meta_data( $meta->key, $meta->value, true );
					}

					$order->add_item( $newItem );
				}
			} else {
				$order->add_item( clone $item );
			}
		}

		// Clone or set new shipping method based on the setting.
		foreach ( $originalOrder->get_items( 'shipping' ) as $shippingItem ) {
			$newShippingItem = new \WC_Order_Item_Shipping();
			$newShippingItem->set_method_title( $shippingItem->get_method_title() );
			$newShippingItem->set_method_id( $shippingItem->get_method_id() );
			$newShippingItem->set_total( $shippingItem->get_total() );
			$newShippingItem->set_taxes( $shippingItem->get_taxes() );

			foreach ( $shippingItem->get_meta_data() as $meta ) {
				$newShippingItem->add_meta_data( $meta->key, $meta->value, true );
			}

			$order->add_item( $newShippingItem );
		}

		// Coupon items.
		foreach ( $originalOrder->get_items( 'coupon' ) as $couponItem ) {
			$newCouponItem = new \WC_Order_Item_Coupon();
			$newCouponItem->set_code( $couponItem->get_code() );
			$newCouponItem->set_discount( $couponItem->get_discount() );
			$order->add_item( $newCouponItem );
		}

		$order->calculate_totals();
		$order->update_status( 'pending' );
		$order->set_address( $orderData['billing'], 'billing' );
		$order->set_address( $orderData['shipping'], 'shipping' );

		// Set the order's date created.
		$current_date = current_time( 'mysql' );
		$order->set_date_created( $current_date );
		$order->add_order_note( sprintf( 'This order was duplicated from order %d.', $originalOrder->get_id() ) );
		$order->save();

		// Re-enable stock management and adjust stock levels manually.
		remove_filter( 'woocommerce_can_reduce_order_stock', '__return_false' );

		foreach ( $order->get_items() as $item ) {
			$product  = $item->get_product();
			$quantity = $item->get_quantity();
			if ( $product && $product->managing_stock() && $product->get_stock_quantity() > 0 ) {
				wc_update_product_stock( $product, $quantity, 'decrease' );
			}
		}

		// Enable all WooCommerce order status emails.
		remove_filter( 'woocommerce_email_enabled_new_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_cancelled_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_failed_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_customer_on_hold_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_customer_processing_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_customer_completed_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_customer_refunded_order', '__return_false' );
		remove_filter( 'woocommerce_email_enabled_customer_invoice', '__return_false' );

		return $order->get_id();
	}

	// Run all function to copy details
	private function duplicateDetails( $newPostId, $post ) {
		$this->copyPostMeta( $newPostId, $post );
		$this->copyChildrens( $newPostId, $post );
		$this->copyComments( $newPostId, $post );
		$this->copyTaxonomies( $newPostId, $post );
		if ( 'shop_order' === $post->post_type ) {
			$this->copyOrderDetails( $newPostId, $post );
		}
	}
	// Duplicate post meta
	private function copyPostMeta( $newPostId, $post ) {
		$metaKeys = get_post_custom_keys( $post->ID );
		if ( empty( $metaKeys ) ) {
			return;
		}

		foreach ( $metaKeys as $metaKey ) {
			$metaValues = get_post_custom_values( $metaKey, $post->ID );
			foreach ( $metaValues as $metaValue ) {
				$metaValue = maybe_unserialize( $metaValue );
				add_post_meta( $newPostId, $metaKey, wp_slash( $metaValue ) );
			}
		}
	}
	// Duplicate all children post
	private function copyChildrens( $newPostId, $post ) {
		$postChildren = get_posts(
			array(
				'post_type'   => 'any',
				'numberposts' => -1,
				'post_status' => 'any',
				'post_parent' => $post->ID,
			)
		);
		foreach ( $postChildren as $children ) {
			if ( 'attachment' === $children->post_type ) {
				continue;
			}
			$this->createDuplicate( $children, $newPostId );
		}
	}
	// Duplicate all comments of post
	private function copyComments( $newPostId, $post ) {
		$comments = get_comments(
			array(
				'post_id' => $post->ID,
				'order'   => 'ASC',
				'orderby' => 'comment_date_gmt',
			)
		);

		$parentId = array();
		foreach ( $comments as $comment ) {
			// do not copy pingbacks or trackbacks
			if ( 'pingback' === $comment->comment_type || 'trackback' === $comment->comment_type ) {
				continue;
			}
			$parent                           = ( $comment->comment_parent && $parentId[ $comment->comment_parent ] ) ? $parentId[ $comment->comment_parent ] : 0;
			$newComment                       = array(
				'comment_post_ID'      => $newPostId,
				'comment_author'       => $comment->comment_author,
				'comment_author_email' => $comment->comment_author_email,
				'comment_author_url'   => $comment->comment_author_url,
				'comment_content'      => $comment->comment_content,
				'comment_type'         => $comment->comment_type,
				'comment_parent'       => $parent,
				'user_id'              => $comment->user_id,
				'comment_author_IP'    => $comment->comment_author_IP,
				'comment_agent'        => $comment->comment_agent,
				'comment_karma'        => $comment->comment_karma,
				'comment_approved'     => $comment->comment_approved,
				'comment_date'         => $comment->comment_date,
				'comment_date_gmt'     => get_gmt_from_date( $comment->comment_date ),
			);
			$newCommentId                     = wp_insert_comment( $newComment );
			$parentId[ $comment->comment_ID ] = $newCommentId;
		}
	}
	// Duplicate post taxonomies
	private function copyTaxonomies( $newPostId, $post ) {
		global $wpdb;
		if ( isset( $wpdb->terms ) ) {
			wp_set_object_terms( $newPostId, null, 'category' );
			$taxonomies = get_object_taxonomies( $post->post_type );

			if ( post_type_supports( $post->post_type, 'post-formats' ) && ! in_array( 'post_format', $taxonomies ) ) {
				$taxonomies[] = 'post_format';
			}

			foreach ( $taxonomies as $taxonomy ) {
				$postTerms = wp_get_object_terms( $post->ID, $taxonomy, array( 'orderby' => 'term_order' ) );
				$terms     = array();
				for ( $i = 0; $i < count( $postTerms ); $i++ ) {
					$terms[] = $postTerms[ $i ]->slug;
				}
				wp_set_object_terms( $newPostId, $terms, $taxonomy );
			}
		}
	}
	//Duplicate order details
	private function copyOrderDetails( $newPostId, $post ) {
		$order     = wc_get_order( $post->ID );
		$copyOrder = wc_get_order( $newPostId );
		foreach ( $order->get_items() as $item ) {
			$products = wc_get_product( $item->get_product_id() );
			$quantity = $item->get_quantity();
			$copyOrder->add_product( $products, $quantity );
		}

		$orderMetaFields = array(
			'customer_id',
			'billing_first_name',
			'billing_last_name',
			'billing_company',
			'billing_address_1',
			'billing_address_2',
			'billing_city',
			'billing_state',
			'billing_postcode',
			'billing_country',
			'billing_email',
			'billing_phone',
			'shipping_first_name',
			'shipping_last_name',
			'shipping_company',
			'shipping_address_1',
			'shipping_address_2',
			'shipping_city',
			'shipping_state',
			'shipping_postcode',
			'shipping_country',
			'created_via',
		);
		foreach ( $orderMetaFields as $metaField ) {
			$setMetaFunction = "set_{$metaField}";
			$getMetaFunction = "get_{$metaField}";
			$copyOrder->$setMetaFunction( $order->$getMetaFunction() );
		}

		$orderTax      = $order->get_items( 'tax' );
		$orderShipping = $order->get_items( 'shipping' );
		$orderFee      = $order->get_items( 'fee' );
		$orderCoupon   = $order->get_items( 'coupon' );
		foreach ( $orderTax as $tax ) {
			$copyOrder->add_item( $tax );
		}
		foreach ( $orderShipping as $shipping ) {
			$copyOrder->add_item( $shipping );
		}
		foreach ( $orderFee as $fee ) {
			$copyOrder->add_item( $fee );
		}
		foreach ( $orderCoupon as $coupon ) {
			$copyOrder->add_item( $coupon );
		}
		$copyOrder->calculate_totals();
		$copyOrder->save();
	}
}