HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/wp-cloud-client/1.1.2/src/Integration/WooCommerceHelper.php
<?php

declare(strict_types=1);

namespace VPlugins\WPCloudClient\Integration;

final class WooCommerceHelper {

	/**
	 * Check whether WooCommerce is active.
	 *
	 * @return bool True if WooCommerce plugin is active.
	 */
	public static function isActive(): bool {
		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		return is_plugin_active( 'woocommerce/woocommerce.php' );
	}

	/**
	 * Retrieve WooCommerce products.
	 *
	 * @param int $offset The number of products to skip.
	 * @param int $limit  The maximum number of products to return.
	 * @return array The list of extracted product data.
	 */
	public static function getProducts( int $offset = 0, int $limit = 10 ): array {
		if ( ! function_exists( 'wc_get_products' ) ) {
			return [];
		}

		try {
			$products = wc_get_products(
				[
					'offset' => $offset,
					'limit'  => $limit,
				]
			);

			$result = [];
			foreach ( $products as $product ) {
				$result[] = self::extractProduct( $product );
			}

			return $result;
		} catch ( \Throwable $e ) {
			error_log( '[WP Cloud Client] WooCommerceHelper::getProducts failed: ' . $e->getMessage() );
			return [];
		}
	}

	/**
	 * Retrieve WooCommerce orders.
	 *
	 * @param int $offset The number of orders to skip.
	 * @param int $limit  The maximum number of orders to return.
	 * @return array The list of extracted order data.
	 */
	public static function getOrders( int $offset = 0, int $limit = 10 ): array {
		if ( ! function_exists( 'wc_get_orders' ) ) {
			return [];
		}

		try {
			$orders = wc_get_orders(
				[
					'offset' => $offset,
					'limit'  => $limit,
				]
			);

			$result = [];
			foreach ( $orders as $order ) {
				$result[] = self::extractOrder( $order );
			}

			return $result;
		} catch ( \Throwable $e ) {
			error_log( '[WP Cloud Client] WooCommerceHelper::getOrders failed: ' . $e->getMessage() );
			return [];
		}
	}

	/**
	 * Sync a business profile into WooCommerce store settings.
	 *
	 * @param array $profile The business profile data to sync.
	 * @return array<string, string>|null The written options or null if inactive.
	 */
	public static function syncProfile( array $profile ): ?array {
		if ( empty( $profile ) || ! self::isActive() ) {
			return null;
		}

		$options = [
			'store_address'   => $profile['address'] ?? '',
			'store_address_2' => '',
			'store_city'      => $profile['city'] ?? '',
			'default_country' => ( $profile['country'] ?? '' ) . ':' . ( $profile['state'] ?? '*' ),
			'store_postcode'  => $profile['zip'] ?? '',
		];

		foreach ( $options as $key => $value ) {
			update_option( "woocommerce_{$key}", $value );
		}

		return $options;
	}

	/**
	 * Extract relevant fields from a WooCommerce product object.
	 *
	 * @param object $product The WooCommerce product object.
	 * @return array The extracted product data.
	 */
	public static function extractProduct( object $product ): array {
		$fields = [ 'id', 'name', 'price', 'regular_price', 'sale_price', 'status', 'stock_status' ];
		$result = [];

		foreach ( $fields as $field ) {
			$method = "get_{$field}";
			if ( method_exists( $product, $method ) ) {
				$result[ $field ] = $product->$method();
			}
		}

		if ( isset( $result['id'] ) ) {
			$result['id'] = (string) $result['id'];
		}

		return $result;
	}

	/**
	 * Extract relevant fields from a WooCommerce order object.
	 *
	 * @param object $order The WooCommerce order object.
	 * @return array The extracted order data.
	 */
	public static function extractOrder( object $order ): array {
		$fields = [
			'id',
			'status',
			'total',
			'currency',
			'date_created',
			'date_modified',
			'date_completed',
			'date_paid',
			'payment_method',
			'payment_method_title',
			'cart_tax',
			'discount_tax',
			'discount_total',
			'shipping_tax',
			'shipping_total',
			'total_tax',
			'prices_include_tax',
			'billing_first_name',
			'billing_last_name',
			'billing_phone',
			'billing_email',
			'billing_country',
			'billing_state',
			'billing_city',
		];

		$result = [];

		foreach ( $fields as $field ) {
			$method = "get_{$field}";
			if ( method_exists( $order, $method ) ) {
				$result[ $field ] = $order->$method();
			}
		}

		if ( isset( $result['id'] ) ) {
			$result['id'] = (string) $result['id'];
		}

		$floatFields = [ 'cart_tax', 'discount_tax', 'discount_total', 'shipping_tax', 'shipping_total', 'total', 'total_tax' ];
		foreach ( $floatFields as $key ) {
			if ( isset( $result[ $key ] ) ) {
				$result[ $key ] = (float) $result[ $key ];
			}
		}

		$dateFields = [ 'date_completed', 'date_created', 'date_modified', 'date_paid' ];
		foreach ( $dateFields as $key ) {
			if ( isset( $result[ $key ] ) && $result[ $key ] instanceof \DateTime ) {
				$result[ $key ] = $result[ $key ]->format( \DateTimeInterface::RFC3339 );
			} elseif ( isset( $result[ $key ] ) && is_object( $result[ $key ] ) && method_exists( $result[ $key ], 'format' ) ) {
				$result[ $key ] = $result[ $key ]->format( \DateTimeInterface::RFC3339 );
			}
		}

		// Extract order items
		if ( method_exists( $order, 'get_items' ) ) {
			$items = $order->get_items();
			if ( is_array( $items ) ) {
				$result['items'] = array_values(
					array_filter(
						array_map(
							[ self::class, 'extractOrderItem' ],
							array_values( $items ),
						)
					)
				);
			}
		}

		return $result;
	}

	/**
	 * Extract relevant fields from a WooCommerce order item.
	 *
	 * @param mixed $item The WooCommerce order item.
	 * @return array|false The extracted item data or false if not a product item.
	 */
	private static function extractOrderItem( mixed $item ): array|false {
		if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) {
			return false;
		}

		$result = [];

		$result['quantity'] = $item->get_quantity();
		$result['total']    = (float) $item->get_total();

		$product = $item->get_product();
		if ( $product ) {
			$extracted = self::extractProduct( $product );
			if ( isset( $extracted['id'] ) ) {
				$result['product_id'] = $extracted['id'];
			}
			if ( isset( $extracted['name'] ) ) {
				$result['product_name'] = $extracted['name'];
			}
		}

		return $result;
	}
}