|
| 1 | +<?php |
| 2 | +/** |
| 3 | + * Ecommerce site type service. |
| 4 | + * |
| 5 | + * @package NewfoldLabs\WP\Module\Onboarding\Services\SiteTypes |
| 6 | + */ |
| 7 | + |
| 8 | +namespace NewfoldLabs\WP\Module\Onboarding\Services\SiteTypes; |
| 9 | + |
| 10 | +use NewfoldLabs\WP\Module\Installer\Services\PluginInstaller; |
| 11 | +use NewfoldLabs\WP\Module\Installer\TaskManagers\PluginActivationTaskManager; |
| 12 | +use NewfoldLabs\WP\Module\Installer\TaskManagers\PluginInstallTaskManager; |
| 13 | +use NewfoldLabs\WP\Module\Installer\Tasks\PluginActivationTask; |
| 14 | +use NewfoldLabs\WP\Module\Installer\Tasks\PluginInstallTask; |
| 15 | +use NewfoldLabs\WP\Module\Onboarding\Data\Plugins as LegacyPlugins; |
| 16 | + |
| 17 | +/** |
| 18 | + * Ecommerce site type service. |
| 19 | + */ |
| 20 | +class EcommerceSiteTypeService { |
| 21 | + |
| 22 | + /** |
| 23 | + * Publishes a WooCommerce product. |
| 24 | + * |
| 25 | + * @param array $product The product. |
| 26 | + * @return int|WP_Error The product ID. |
| 27 | + */ |
| 28 | + public static function publish_woo_product( string $name, string $description, mixed $price, string $image_url = '', array $categories = array()) { |
| 29 | + // Remove hooks that can slow down the operation. |
| 30 | + remove_all_actions('woocommerce_new_product'); |
| 31 | + remove_all_actions('woocommerce_update_product'); |
| 32 | + remove_all_actions('wp_insert_post'); |
| 33 | + remove_all_actions('save_post'); |
| 34 | + |
| 35 | + $product_data = array( |
| 36 | + 'post_title' => $name, |
| 37 | + 'post_content' => '', |
| 38 | + 'post_excerpt' => $description, |
| 39 | + 'post_status' => 'publish', |
| 40 | + 'post_type' => 'product', |
| 41 | + 'post_author' => get_current_user_id() ?: 1, |
| 42 | + ); |
| 43 | + // Insert product. |
| 44 | + $product_id = wp_insert_post( $product_data ); |
| 45 | + // Validate product was created successfully. |
| 46 | + if ( is_wp_error( $product_id ) || !$product_id ) { |
| 47 | + return new \WP_Error( 'error_publishing_woo_product', 'Failed to create product' ); |
| 48 | + } |
| 49 | + // Product meta. |
| 50 | + update_post_meta( $product_id, '_regular_price', $price ); |
| 51 | + update_post_meta( $product_id, '_price', $price ); |
| 52 | + update_post_meta( $product_id, '_stock_status', 'instock' ); |
| 53 | + update_post_meta( $product_id, '_manage_stock', 'no' ); |
| 54 | + // Product categories. |
| 55 | + if ( ! empty( $categories ) ) { |
| 56 | + $category_ids = array(); |
| 57 | + foreach ( $categories as $category ) { |
| 58 | + $category_ids[] = self::create_or_get_woo_category( $category ); |
| 59 | + } |
| 60 | + wp_set_post_terms( $product_id, $category_ids, 'product_cat' ); |
| 61 | + } |
| 62 | + // Featured image. |
| 63 | + if ( ! empty( $image_url ) ) { |
| 64 | + self::set_woo_product_featured_image_from_url( $image_url, $product_id ); |
| 65 | + } |
| 66 | + |
| 67 | + return $product_id; |
| 68 | + } |
| 69 | + |
| 70 | + /** |
| 71 | + * Sets the featured image for a WooCommerce product. |
| 72 | + * |
| 73 | + * @param string $image_url The URL of the image. |
| 74 | + * @param int $product_id The ID of the product. |
| 75 | + * @return void |
| 76 | + */ |
| 77 | + private static function set_woo_product_featured_image_from_url( string $image_url, int $product_id ): void { |
| 78 | + $image_id = self::import_image_from_url( $image_url, $product_id ); |
| 79 | + if ( $image_id ) { |
| 80 | + update_post_meta( $product_id, '_thumbnail_id', $image_id ); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + /** |
| 85 | + * Imports an image from a URL. |
| 86 | + * |
| 87 | + * @param string $image_url The URL of the image. |
| 88 | + * @param int $product_id The ID of the product. |
| 89 | + * @return int The ID of the attachment. |
| 90 | + */ |
| 91 | + private static function import_image_from_url( string $image_url, int $product_id ): int { |
| 92 | + if ( ! function_exists( 'media_handle_sideload' ) ) { |
| 93 | + require_once( ABSPATH . 'wp-admin/includes/media.php' ); |
| 94 | + require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
| 95 | + require_once( ABSPATH . 'wp-admin/includes/image.php' ); |
| 96 | + } |
| 97 | + |
| 98 | + // Add an arbitrary extension to the image URL to trick media_sideload_image to download the image. |
| 99 | + $image_url = $image_url . '?ext=.jpeg'; |
| 100 | + $attachment_id = media_sideload_image( $image_url, $product_id, null, 'id' ); |
| 101 | + if ( is_wp_error( $attachment_id ) ) { |
| 102 | + return 0; |
| 103 | + } |
| 104 | + |
| 105 | + return $attachment_id; |
| 106 | + } |
| 107 | + |
| 108 | + /** |
| 109 | + * Creates or gets a WooCommerce category. |
| 110 | + * |
| 111 | + * @param string $name The name of the category. |
| 112 | + * @return int The ID of the category. |
| 113 | + */ |
| 114 | + public static function create_or_get_woo_category( string $name ): int { |
| 115 | + $category_slug = sanitize_title( $name ); |
| 116 | + $category = get_term_by( 'slug', $category_slug, 'product_cat' ); |
| 117 | + if ( $category ) { |
| 118 | + return $category->term_id; |
| 119 | + } |
| 120 | + $category = wp_insert_term( $name, 'product_cat' ); |
| 121 | + if ( is_wp_error( $category ) ) { |
| 122 | + return 0; |
| 123 | + } |
| 124 | + return $category['term_id']; |
| 125 | + } |
| 126 | + |
| 127 | + /** |
| 128 | + * Gets the ecommerce plugins. |
| 129 | + * |
| 130 | + * @return array |
| 131 | + */ |
| 132 | + public static function get_ecommerce_plugins(): array { |
| 133 | + return LegacyPlugins::get_ecommerce_plugins(); |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * Installs the ecommerce plugins (background task). |
| 138 | + * |
| 139 | + * @return void |
| 140 | + */ |
| 141 | + public static function install_ecommerce_plugins(): void { |
| 142 | + $ecommerce_plugins = self::get_ecommerce_plugins(); |
| 143 | + |
| 144 | + foreach ( $ecommerce_plugins as $plugin ) { |
| 145 | + $plugin_type = PluginInstaller::get_plugin_type( $plugin['slug'] ); |
| 146 | + $plugin_path = PluginInstaller::get_plugin_path( $plugin['slug'], $plugin_type ); |
| 147 | + if ( ! $plugin_path ) { |
| 148 | + continue; |
| 149 | + } |
| 150 | + |
| 151 | + // Checks if a plugin with the given slug and activation criteria already installed. |
| 152 | + if ( PluginInstaller::is_plugin_installed( $plugin_path ) ) { |
| 153 | + // If the plugin is installed, we'll add it to the activation queue. |
| 154 | + PluginActivationTaskManager::add_to_queue( |
| 155 | + new PluginActivationTask( |
| 156 | + $plugin['slug'] |
| 157 | + ) |
| 158 | + ); |
| 159 | + continue; |
| 160 | + } |
| 161 | + |
| 162 | + // If the plugin is not installed, we'll add it to the install/activation queue. |
| 163 | + PluginInstallTaskManager::add_to_queue( |
| 164 | + new PluginInstallTask( |
| 165 | + $plugin['slug'], |
| 166 | + true, |
| 167 | + isset( $plugin['priority'] ) ? $plugin['priority'] : 0 |
| 168 | + ) |
| 169 | + ); |
| 170 | + } |
| 171 | + |
| 172 | + return; |
| 173 | + } |
| 174 | +} |
0 commit comments