{
	"$schema": "https://playground.wordpress.net/blueprint-schema.json",
	"meta": {
		"title": "Force Sells and Smart Bundles Demo",
		"description": "A ready-to-test WooCommerce store with a force-sell product, cart, and checkout.",
		"author": "kmjamsheed0",
		"categories": [
			"ecommerce",
			"woocommerce",
			"demo"
		]
	},
	"landingPage": "/force-sells-demo/",
	"preferredVersions": {
		"php": "8.3",
		"wp": "latest"
	},
	"features": {
		"networking": true
	},
	"steps": [
		{
			"step": "login",
			"username": "admin",
			"password": "password"
		},
		{
			"step": "installPlugin",
			"pluginData": {
				"resource": "wordpress.org/plugins",
				"slug": "woocommerce"
			},
			"options": {
				"activate": true
			}
		},
		{
			"step": "installPlugin",
			"pluginData": {
				"resource": "wordpress.org/plugins",
				"slug": "jkm-force-sells"
			},
			"options": {
				"activate": true
			}
		},
		{
			"step": "installTheme",
			"themeData": {
				"resource": "wordpress.org/themes",
				"slug": "storefront"
			},
			"options": {
				"activate": true
			}
		},
		{
			"step": "setSiteOptions",
			"options": {
				"blogname": "Force Sells Demo Store",
				"blogdescription": "Optional and mandatory WooCommerce add-ons in action",
				"woocommerce_store_address": "123 Demo Street",
				"woocommerce_store_city": "Playground",
				"woocommerce_store_postcode": "94103",
				"woocommerce_default_country": "US:CA",
				"woocommerce_currency": "USD",
				"woocommerce_weight_unit": "lbs",
				"woocommerce_dimension_unit": "in",
				"woocommerce_allow_tracking": "no"
			}
		},
		{
			"step": "runPHP",
			"code": "<?php\nrequire_once '/wordpress/wp-load.php';\nrequire_once ABSPATH . 'wp-admin/includes/plugin.php';\n\nforeach ( array( 'woocommerce/woocommerce.php', 'jkm-force-sells/jkm-force-sells.php' ) as $plugin_file ) {\n\tif ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_file ) && ! is_plugin_active( $plugin_file ) ) {\n\t\tactivate_plugin( $plugin_file );\n\t}\n}\n\nif ( ! class_exists( 'WC_Product_Simple' ) ) {\n\t$wc_plugin_file = WP_PLUGIN_DIR . '/woocommerce/woocommerce.php';\n\n\tif ( file_exists( $wc_plugin_file ) ) {\n\t\trequire_once $wc_plugin_file;\n\t}\n}\n\nif ( ! class_exists( 'WC_Product_Simple' ) ) {\n\techo 'WooCommerce is not active. Skipping Force Sells demo setup.';\n\texit( 0 );\n}\n\nif ( class_exists( 'WC_Install' ) ) {\n\tWC_Install::create_pages();\n}\n\nupdate_option( 'woocommerce_store_address', '123 Demo Street' );\nupdate_option( 'woocommerce_store_city', 'Playground' );\nupdate_option( 'woocommerce_store_postcode', '94103' );\nupdate_option( 'woocommerce_default_country', 'US:CA' );\nupdate_option( 'woocommerce_currency', 'USD' );\nupdate_option( 'woocommerce_weight_unit', 'lbs' );\nupdate_option( 'woocommerce_dimension_unit', 'in' );\nupdate_option( 'woocommerce_allow_tracking', 'no' );\nupdate_option( 'woocommerce_enable_guest_checkout', 'yes' );\nupdate_option( 'woocommerce_enable_checkout_login_reminder', 'no' );\nupdate_option( 'woocommerce_enable_signup_and_login_from_checkout', 'no' );\nupdate_option( 'woocommerce_calc_taxes', 'no' );\nupdate_option( 'woocommerce_onboarding_profile', array( 'skipped' => true ) );\nupdate_option( 'woocommerce_cod_settings', array( 'enabled' => 'yes', 'title' => 'Cash on delivery' ) );\nupdate_option( 'woocommerce_bacs_settings', array( 'enabled' => 'yes', 'title' => 'Direct bank transfer' ) );\nupdate_option(\n\t'jkmfs_settings',\n\tarray(\n\t\t'display_position'    => 'woocommerce_before_add_to_cart_button',\n\t\t'display_type'        => 'grid',\n\t\t'show_images'         => 'yes',\n\t\t'show_price'          => 'yes',\n\t\t'custom_message_text' => 'This demo product automatically adds a mandatory synced filter pack and an optional storage tin:',\n\t)\n);\n\nfunction jkmfs_blueprint_setup_shipping() {\n\tif ( ! class_exists( 'WC_Shipping_Zones' ) || ! class_exists( 'WC_Shipping_Zone' ) ) {\n\t\treturn;\n\t}\n\n\t$zone_id = 0;\n\t$zones   = WC_Shipping_Zones::get_zones();\n\n\tforeach ( $zones as $zone_data ) {\n\t\tif ( isset( $zone_data['zone_name'] ) && 'United States' === $zone_data['zone_name'] ) {\n\t\t\t$zone_id = (int) $zone_data['zone_id'];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t$zone = new WC_Shipping_Zone( $zone_id );\n\t$zone->set_zone_name( 'United States' );\n\t$zone->set_zone_order( 0 );\n\t$zone->save();\n\n\t$has_us_location = false;\n\n\tforeach ( $zone->get_zone_locations() as $location ) {\n\t\tif ( 'country' === $location->type && 'US' === $location->code ) {\n\t\t\t$has_us_location = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif ( ! $has_us_location ) {\n\t\t$zone->add_location( 'US', 'country' );\n\t}\n\n\t$flat_rate_instance_id = 0;\n\n\tforeach ( $zone->get_shipping_methods( true ) as $shipping_method ) {\n\t\tif ( 'flat_rate' === $shipping_method->id ) {\n\t\t\t$flat_rate_instance_id = (int) $shipping_method->instance_id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif ( ! $flat_rate_instance_id ) {\n\t\t$flat_rate_instance_id = $zone->add_shipping_method( 'flat_rate' );\n\t}\n\n\tupdate_option(\n\t\t'woocommerce_flat_rate_' . $flat_rate_instance_id . '_settings',\n\t\tarray(\n\t\t\t'title'      => 'Flat rate',\n\t\t\t'tax_status' => 'none',\n\t\t\t'cost'       => '5.00',\n\t\t)\n\t);\n}\n\nrequire_once ABSPATH . 'wp-admin/includes/media.php';\nrequire_once ABSPATH . 'wp-admin/includes/file.php';\nrequire_once ABSPATH . 'wp-admin/includes/image.php';\n\nfunction jkmfs_blueprint_attach_product_image( $image_url, $product_id, $filename ) {\n\t$tmp = download_url( $image_url );\n\n\tif ( is_wp_error( $tmp ) ) {\n\t\treturn false;\n\t}\n\n\t$file_array = array(\n\t\t'name'     => $filename,\n\t\t'tmp_name' => $tmp,\n\t);\n\n\t$attachment_id = media_handle_sideload( $file_array, $product_id );\n\n\t@unlink( $tmp );\n\n\tif ( is_wp_error( $attachment_id ) ) {\n\t\treturn false;\n\t}\n\n\tset_post_thumbnail( $product_id, $attachment_id );\n\n\t$product = wc_get_product( $product_id );\n\n\tif ( $product ) {\n\t\t$product->set_image_id( $attachment_id );\n\t\t$product->save();\n\t}\n\n\treturn $attachment_id;\n}\n\nfunction jkmfs_blueprint_create_product( $product_data ) {\n\t$product_id = wc_get_product_id_by_sku( $product_data['sku'] );\n\n\tif ( ! $product_id && ! empty( $product_data['id'] ) && ! get_post( $product_data['id'] ) ) {\n\t\t$product_id = wp_insert_post(\n\t\t\tarray(\n\t\t\t\t'import_id'    => (int) $product_data['id'],\n\t\t\t\t'post_title'   => $product_data['name'],\n\t\t\t\t'post_name'    => $product_data['slug'],\n\t\t\t\t'post_status'  => 'publish',\n\t\t\t\t'post_type'    => 'product',\n\t\t\t\t'post_content' => $product_data['description'],\n\t\t\t\t'post_excerpt' => $product_data['short_description'],\n\t\t\t),\n\t\t\ttrue\n\t\t);\n\n\t\tif ( is_wp_error( $product_id ) ) {\n\t\t\t$product_id = 0;\n\t\t}\n\t}\n\n\t$product = $product_id ? new WC_Product_Simple( $product_id ) : new WC_Product_Simple();\n\n\t$product->set_name( $product_data['name'] );\n\t$product->set_slug( $product_data['slug'] );\n\t$product->set_sku( $product_data['sku'] );\n\t$product->set_status( 'publish' );\n\t$product->set_catalog_visibility( 'visible' );\n\t$product->set_regular_price( $product_data['regular_price'] );\n\t$product->set_price( $product_data['regular_price'] );\n\t$product->set_description( $product_data['description'] );\n\t$product->set_short_description( $product_data['short_description'] );\n\t$product->set_manage_stock( false );\n\t$product->set_stock_status( 'instock' );\n\t$product->set_virtual( true );\n\t$product->set_sold_individually( false );\n\n\t$product_id = $product->save();\n\n\tif ( ! empty( $product_data['image_url'] ) ) {\n\t\tjkmfs_blueprint_attach_product_image( $product_data['image_url'], $product_id, $product_data['image_name'] );\n\t}\n\n\treturn $product_id;\n}\n\njkmfs_blueprint_setup_shipping();\n\n$main_product_id = jkmfs_blueprint_create_product(\n\tarray(\n\t\t'id'                => 1001,\n\t\t'name'              => 'Coffee Starter Kit',\n\t\t'slug'              => 'coffee-starter-kit',\n\t\t'sku'               => 'jkmfs-coffee-kit',\n\t\t'regular_price'     => '49.00',\n\t\t'short_description' => 'Add this product to the cart to see optional and mandatory force-sell products added automatically.',\n\t\t'description'       => 'This product is configured for the Force Sells and Smart Bundles demo. It has one mandatory synced add-on and one optional add-on so you can test both workflows from the product page, cart, and checkout.',\n\t\t'image_url'         => 'https://placehold.co/900x900/4f3422/f8efe5.png?text=Coffee+Starter+Kit',\n\t\t'image_name'        => 'coffee-starter-kit.png',\n\t)\n);\n\n$mandatory_product_id = jkmfs_blueprint_create_product(\n\tarray(\n\t\t'id'                => 1002,\n\t\t'name'              => 'Reusable Coffee Filter Pack',\n\t\t'slug'              => 'reusable-coffee-filter-pack',\n\t\t'sku'               => 'jkmfs-filter-pack',\n\t\t'regular_price'     => '8.00',\n\t\t'short_description' => 'Mandatory force-sell item synced to the main product quantity.',\n\t\t'description'       => 'This mandatory add-on is forcefully added with the Coffee Starter Kit. Its quantity stays synced with the parent item.',\n\t\t'image_url'         => 'https://placehold.co/900x900/2f6f53/e9fff1.png?text=Reusable+Filter+Pack',\n\t\t'image_name'        => 'reusable-coffee-filter-pack.png',\n\t)\n);\n\n$optional_product_id = jkmfs_blueprint_create_product(\n\tarray(\n\t\t'id'                => 1003,\n\t\t'name'              => 'Coffee Storage Tin',\n\t\t'slug'              => 'coffee-storage-tin',\n\t\t'sku'               => 'jkmfs-storage-tin',\n\t\t'regular_price'     => '14.00',\n\t\t'short_description' => 'Optional force-sell item that can be removed independently.',\n\t\t'description'       => 'This optional add-on is added with the Coffee Starter Kit but can be removed from the cart without removing the parent product.',\n\t\t'image_url'         => 'https://placehold.co/900x900/315a74/eaf6ff.png?text=Coffee+Storage+Tin',\n\t\t'image_name'        => 'coffee-storage-tin.png',\n\t)\n);\n\n$main_product = wc_get_product( $main_product_id );\n\nif ( $main_product ) {\n\t$main_product->update_meta_data( 'jkm_meta_force_sell_ids', array( $optional_product_id ) );\n\t$main_product->update_meta_data( 'jkm_meta_force_sell_synced_ids', array( $mandatory_product_id ) );\n\t$main_product->save();\n}\n\nfunction jkmfs_blueprint_upsert_page( $slug, $title, $content ) {\n\t$page = get_page_by_path( $slug );\n\n\tif ( $page ) {\n\t\twp_update_post(\n\t\t\tarray(\n\t\t\t\t'ID'           => $page->ID,\n\t\t\t\t'post_title'   => $title,\n\t\t\t\t'post_content' => $content,\n\t\t\t)\n\t\t);\n\n\t\treturn $page->ID;\n\t}\n\n\treturn wp_insert_post(\n\t\tarray(\n\t\t\t'post_title'   => $title,\n\t\t\t'post_name'    => $slug,\n\t\t\t'post_status'  => 'publish',\n\t\t\t'post_type'    => 'page',\n\t\t\t'post_content' => $content,\n\t\t)\n\t);\n}\n\n$cart_page_id     = jkmfs_blueprint_upsert_page( 'cart', 'Cart', '[woocommerce_cart]' );\n$checkout_page_id = jkmfs_blueprint_upsert_page( 'checkout', 'Checkout', '[woocommerce_checkout]' );\n$shop_page_id     = jkmfs_blueprint_upsert_page( 'shop', 'Shop', '<!-- wp:shortcode -->[products limit=\"12\" columns=\"3\"]<!-- /wp:shortcode -->' );\n\n$add_to_cart_url = add_query_arg( 'add-to-cart', $main_product_id, home_url( '/cart/' ) );\n$product_url     = get_permalink( $main_product_id );\n$settings_url    = admin_url( 'edit.php?post_type=product&page=jkmfs_force_sell_settings' );\n\n$demo_page_content = '<!-- wp:heading --><h2>Force Sells demo</h2><!-- /wp:heading -->'\n\t. '<!-- wp:paragraph --><p>Use the Coffee Starter Kit to test optional and mandatory force-sell products in WooCommerce.</p><!-- /wp:paragraph -->'\n\t. '<!-- wp:list --><ul><li>Automatically adds the selected add-on products when the bundle product is added to the cart.</li><li>Keeps the mandatory filter pack synced with the parent product quantity.</li><li>Allows the optional storage tin to be removed independently from the cart.</li><li>Shows add-on products with images, prices, and a custom product-page message.</li><li>Works with the standard cart and checkout flow in this Playground demo.</li></ul><!-- /wp:list -->'\n\t. '<!-- wp:buttons --><div class=\"wp-block-buttons\">'\n\t. '<!-- wp:button --><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"' . esc_url( $product_url ) . '\">View bundle product</a></div><!-- /wp:button -->'\n\t. '<!-- wp:button --><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"' . esc_url( $add_to_cart_url ) . '\">Add to cart</a></div><!-- /wp:button -->'\n\t. '<!-- wp:button --><div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"' . esc_url( $settings_url ) . '\">Plugin settings</a></div><!-- /wp:button -->'\n\t. '</div><!-- /wp:buttons -->';\n\njkmfs_blueprint_upsert_page( 'force-sells-demo', 'Force Sells Demo', $demo_page_content );\n\nupdate_option( 'woocommerce_cart_page_id', $cart_page_id );\nupdate_option( 'woocommerce_checkout_page_id', $checkout_page_id );\nupdate_option( 'woocommerce_shop_page_id', $shop_page_id );\nupdate_option( 'permalink_structure', '/%postname%/' );\nflush_rewrite_rules();\n\necho 'Force Sells demo store ready. Main product ID: ' . absint( $main_product_id );"
		}
	]
}
