{
  "$schema": "https://playground.wordpress.net/blueprint-schema.json",
  "landingPage": "/",
  "login": true,
  "preferredVersions": {
    "php": "8.2",
    "wp": "6.9"
  },
  "steps": [
    {
      "step": "installPlugin",
      "pluginData": {
        "resource": "wordpress.org/plugins",
        "slug": "woocommerce"
      },
      "options": {
        "activate": true
      }
    },
    {
      "step": "installPlugin",
      "pluginData": {
        "resource": "wordpress.org/plugins",
        "slug": "flexible-shipping"
      },
      "options": {
        "activate": true
      }
    },
    {
      "step": "installTheme",
      "themeZipFile": {
        "resource": "wordpress.org/themes",
        "slug": "storefront"
      },
      "options": {
        "activate": true
      }
    },
    {
      "step": "setSiteOptions",
      "options": {
        "blogname": "Flexible Shipping Playground",
        "blogdescription": "Playground for Flexible Shipping scenarios",
        "site_visibility": "0",
        "woocommerce_default_country": "US:NY",
        "woocommerce_currency": "USD",
        "woocommerce_store_address": "Test street 1",
        "woocommerce_store_city": "New York",
        "woocommerce_store_postcode": "10001",
        "woocommerce_weight_unit": "kg",
        "woocommerce_dimension_unit": "cm",
        "woocommerce_allow_tracking": "no",
        "woocommerce_store_state": "NY",
        "woocommerce_default_customer_address": "base"
      }
    },
    {
      "step": "runPHP",
      "code": "<?php\nrequire_once 'wordpress/wp-load.php';\n\nif ( class_exists( 'WC_Install' ) ) {\n\tWC_Install::create_pages();\n}\n\nupdate_option( 'woocommerce_default_country', 'US:NY' );\nupdate_option( 'woocommerce_currency', 'USD' );\nupdate_option( 'woocommerce_store_address', 'Test street 1' );\nupdate_option( 'woocommerce_store_city', 'New York' );\nupdate_option( 'woocommerce_store_postcode', '10001' );\nupdate_option( 'woocommerce_store_state', 'NY' );\nupdate_option( 'woocommerce_default_customer_address', 'base' );\nupdate_option( 'woocommerce_weight_unit', 'kg' );\nupdate_option( 'woocommerce_dimension_unit', 'cm' );\nupdate_option( 'woocommerce_allow_tracking', 'no' );\nupdate_option( 'woocommerce_coming_soon', 'no' );\n\nif ( function_exists( 'wc_get_page_id' ) ) {\n\t$shop_page_id = (int) wc_get_page_id( 'shop' );\n\tif ( $shop_page_id > 0 ) {\n\t\tupdate_option( 'show_on_front', 'page' );\n\t\tupdate_option( 'page_on_front', $shop_page_id );\n\t\tupdate_option( 'page_for_posts', 0 );\n\t}\n\n\t$free_shipping_notice_block = implode(\n\t\t\"\\n\",\n\t\t[\n\t\t\t'<!-- wp:flexible-shipping/free-shipping-notice -->',\n\t\t\t'<div class=\"wp-block-flexible-shipping-free-shipping-notice\">Flexible Shipping Free Shipping</div>',\n\t\t\t'<!-- /wp:flexible-shipping/free-shipping-notice -->',\n\t\t]\n\t);\n\n\t$prepend_free_shipping_notice_to_page = static function ( $page_id, $fallback_main_block ) use ( $free_shipping_notice_block ) {\n\t\tif ( $page_id <= 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$page = get_post( $page_id );\n\t\tif ( ! $page instanceof WP_Post ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$current_content     = is_string( $page->post_content ) ? $page->post_content : '';\n\t\t$legacy_notice_block = '<!-- wp:flexible-shipping/free-shipping-notice /-->';\n\t\tif ( false !== strpos( $current_content, $legacy_notice_block ) ) {\n\t\t\twp_update_post(\n\t\t\t\t[\n\t\t\t\t\t'ID'           => $page_id,\n\t\t\t\t\t'post_content' => str_replace( $legacy_notice_block, $free_shipping_notice_block, $current_content ),\n\t\t\t\t]\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif ( false !== strpos( $current_content, '<!-- wp:flexible-shipping/free-shipping-notice -->' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t$main_content = trim( $current_content ) !== '' ? $current_content : $fallback_main_block;\n\n\t\twp_update_post(\n\t\t\t[\n\t\t\t\t'ID'           => $page_id,\n\t\t\t\t'post_content' => $free_shipping_notice_block . \"\\n\\n\" . $main_content,\n\t\t\t]\n\t\t);\n\t};\n\n\t$cart_page_id = (int) wc_get_page_id( 'cart' );\n\t$prepend_free_shipping_notice_to_page(\n\t\t$cart_page_id,\n\t\timplode(\n\t\t\t\"\\n\",\n\t\t\t[\n\t\t\t\t'<!-- wp:woocommerce/cart -->',\n\t\t\t\t'<div class=\"wp-block-woocommerce-cart alignwide is-loading\"></div>',\n\t\t\t\t'<!-- /wp:woocommerce/cart -->',\n\t\t\t]\n\t\t)\n\t);\n\n\t$checkout_page_id = (int) wc_get_page_id( 'checkout' );\n\t$prepend_free_shipping_notice_to_page(\n\t\t$checkout_page_id,\n\t\timplode(\n\t\t\t\"\\n\",\n\t\t\t[\n\t\t\t\t'<!-- wp:woocommerce/checkout -->',\n\t\t\t\t'<div class=\"wp-block-woocommerce-checkout alignwide wc-block-checkout is-loading\"></div>',\n\t\t\t\t'<!-- /wp:woocommerce/checkout -->',\n\t\t\t]\n\t\t)\n\t);\n}\n\nif ( function_exists( 'switch_theme' ) ) {\n\tswitch_theme( 'storefront' );\n}\n\n$default_customer_data = [\n\t'first_name' => 'John',\n\t'last_name'  => 'Doe',\n\t'address_1'  => '123 Broadway Ave',\n\t'address_2'  => 'Apt 4B',\n\t'city'       => 'New York',\n\t'postcode'   => '10001',\n\t'country'    => 'US',\n\t'state'      => 'NY',\n\t'phone'      => '2125550101',\n\t'email'      => 'john.doe@example.com',\n];\n\n$bacs_settings = get_option( 'woocommerce_bacs_settings', [] );\nif ( ! is_array( $bacs_settings ) ) {\n\t$bacs_settings = [];\n}\n$bacs_settings['enabled'] = 'yes';\nif ( empty( $bacs_settings['title'] ) ) {\n\t$bacs_settings['title'] = 'Direct bank transfer';\n}\nif ( empty( $bacs_settings['description'] ) ) {\n\t$bacs_settings['description'] = 'Make your payment directly into our bank account.';\n}\nupdate_option( 'woocommerce_bacs_settings', $bacs_settings );\n\nupdate_option(\n\t'woocommerce_onboarding_profile',\n\t[\n\t\t'completed'            => true,\n\t\t'skipped'              => true,\n\t\t'is_store_country_set' => true,\n\t]\n);\nupdate_option( 'woocommerce_onboarding_profile_progress', [ 'completed' => true ] );\nupdate_option( 'woocommerce_task_list_hidden_lists', [ 'setup', 'extended' ] );\nupdate_option( 'woocommerce_task_list_completed_lists', [ 'setup', 'extended' ] );\nupdate_option( 'woocommerce_task_list_hidden', 'yes' );\nupdate_option( 'woocommerce_extended_task_list_hidden', 'yes' );\nupdate_option( 'woocommerce_task_list_complete', 'yes' );\nupdate_option( 'woocommerce_task_list_reminder_bar_hidden', 'yes' );\nupdate_option( 'woocommerce_task_list_keep_completed', 'no' );\nupdate_option( 'woocommerce_admin_reviewed_store_location_settings', 'yes' );\nupdate_option( 'woocommerce_admin_reviewed_default_shipping_zones', 'yes' );\nupdate_option( 'woocommerce_admin_created_default_shipping_zones', 'yes' );\nupdate_option( 'woocommerce_admin_customize_store_completed', 'yes' );\ndelete_transient( '_wc_activation_redirect' );\n\n$admins = get_users(\n\t[\n\t\t'role'   => 'administrator',\n\t\t'fields' => 'ID',\n\t]\n);\nforeach ( $admins as $admin_id ) {\n\tupdate_user_meta( $admin_id, 'woocommerce_launch_your_store_tour_hidden', 'yes' );\n\tupdate_user_meta( $admin_id, 'woocommerce_admin_launch_your_store_tour_hidden', 'yes' );\n\tupdate_user_meta( $admin_id, 'woocommerce_coming_soon_banner_dismissed', 'yes' );\n\tupdate_user_meta( $admin_id, 'woocommerce_admin_coming_soon_banner_dismissed', 'yes' );\n\n\twp_update_user(\n\t\t[\n\t\t\t'ID'         => $admin_id,\n\t\t\t'first_name' => $default_customer_data['first_name'],\n\t\t\t'last_name'  => $default_customer_data['last_name'],\n\t\t]\n\t);\n\n\tupdate_user_meta( $admin_id, 'billing_first_name', $default_customer_data['first_name'] );\n\tupdate_user_meta( $admin_id, 'billing_last_name', $default_customer_data['last_name'] );\n\tupdate_user_meta( $admin_id, 'billing_address_1', $default_customer_data['address_1'] );\n\tupdate_user_meta( $admin_id, 'billing_address_2', $default_customer_data['address_2'] );\n\tupdate_user_meta( $admin_id, 'billing_city', $default_customer_data['city'] );\n\tupdate_user_meta( $admin_id, 'billing_postcode', $default_customer_data['postcode'] );\n\tupdate_user_meta( $admin_id, 'billing_country', $default_customer_data['country'] );\n\tupdate_user_meta( $admin_id, 'billing_state', $default_customer_data['state'] );\n\tupdate_user_meta( $admin_id, 'billing_phone', $default_customer_data['phone'] );\n\tupdate_user_meta( $admin_id, 'billing_email', $default_customer_data['email'] );\n\n\tupdate_user_meta( $admin_id, 'shipping_first_name', $default_customer_data['first_name'] );\n\tupdate_user_meta( $admin_id, 'shipping_last_name', $default_customer_data['last_name'] );\n\tupdate_user_meta( $admin_id, 'shipping_address_1', $default_customer_data['address_1'] );\n\tupdate_user_meta( $admin_id, 'shipping_address_2', $default_customer_data['address_2'] );\n\tupdate_user_meta( $admin_id, 'shipping_city', $default_customer_data['city'] );\n\tupdate_user_meta( $admin_id, 'shipping_postcode', $default_customer_data['postcode'] );\n\tupdate_user_meta( $admin_id, 'shipping_country', $default_customer_data['country'] );\n\tupdate_user_meta( $admin_id, 'shipping_state', $default_customer_data['state'] );\n}\n\n$existing_products = get_posts(\n\t[\n\t\t'post_type'      => 'product',\n\t\t'post_status'    => [ 'publish', 'private', 'draft', 'pending', 'future' ],\n\t\t'fields'         => 'ids',\n\t\t'posts_per_page' => -1,\n\t]\n);\n\nforeach ( $existing_products as $product_id ) {\n\twp_delete_post( (int) $product_id, true );\n}\n\n$create_product = static function ( $name, $price, $weight, $sku ) {\n\tif ( ! class_exists( 'WC_Product_Simple' ) ) {\n\t\treturn;\n\t}\n\n\t$product = new WC_Product_Simple();\n\t$product->set_name( $name );\n\t$product->set_status( 'publish' );\n\t$product->set_catalog_visibility( 'visible' );\n\t$product->set_regular_price( $price );\n\t$product->set_price( $price );\n\t$product->set_weight( $weight );\n\t$product->set_sku( $sku );\n\t$product->set_manage_stock( false );\n\t$product->set_stock_status( 'instock' );\n\t$product->save();\n};\n\n$create_product( 'Product 1', '1', '1', 'playground-product-1' );\n$create_product( 'Product 2', '2', '2', 'playground-product-2' );\n$create_product( 'Product 3', '1', '3', 'playground-product-3' );\n\nif ( class_exists( 'WC_Shipping_Zone' ) ) {\n\t$zone             = new WC_Shipping_Zone( 0 );\n\t$shipping_methods = $zone->get_shipping_methods( false, 'admin' );\n\n\tif ( is_array( $shipping_methods ) ) {\n\t\tforeach ( $shipping_methods as $shipping_method ) {\n\t\t\tif ( isset( $shipping_method->instance_id ) ) {\n\t\t\t\t$zone->delete_shipping_method( (int) $shipping_method->instance_id );\n\t\t\t}\n\t\t}\n\t}\n\n\t$add_method = static function ( $zone, $title, $rules, $settings_overrides = [] ) {\n\t\t$instance_id = (int) $zone->add_shipping_method( 'flexible_shipping_single' );\n\t\tif ( $instance_id <= 0 ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t$settings = [\n\t\t\t'method_title'                      => $title,\n\t\t\t'method_description'                => '',\n\t\t\t'tax_status'                        => 'none',\n\t\t\t'prices_include_tax'                => 'no',\n\t\t\t'method_enabled'                    => 'yes',\n\t\t\t'method_integration'                => '',\n\t\t\t'method_free_shipping'              => '',\n\t\t\t'method_free_shipping_label'        => '',\n\t\t\t'method_free_shipping_cart_notice'  => 'no',\n\t\t\t'method_free_shipping_notice_text'  => '',\n\t\t\t'method_free_shipping_progress_bar' => 'no',\n\t\t\t'method_calculation_method'         => 'sum',\n\t\t\t'cart_calculation'                  => 'package',\n\t\t\t'method_visibility'                 => 'no',\n\t\t\t'method_default'                    => 'no',\n\t\t\t'method_debug_mode'                 => 'no',\n\t\t\t'method_rules'                      => wp_json_encode( $rules ),\n\t\t\t'id_for_shipping'                   => 'flexible_shipping_single:' . $instance_id,\n\t\t\t'title'                             => $title,\n\t\t];\n\n\t\tif ( ! empty( $settings_overrides ) ) {\n\t\t\t$settings = array_merge( $settings, $settings_overrides );\n\t\t}\n\n\t\tupdate_option( 'woocommerce_flexible_shipping_single_' . $instance_id . '_settings', $settings );\n\n\t\treturn $instance_id;\n\t};\n\n\t$build_rules = static function ( $condition_id ) {\n\t\t$rules = [];\n\n\t\tfor ( $i = 1; $i <= 100; $i++ ) {\n\t\t\t$min     = 1 === $i ? '' : number_format( $i - 0.99, 2, '.', '' );\n\t\t\t$max     = (string) $i;\n\t\t\t$rules[] = [\n\t\t\t\t'conditions'       => [\n\t\t\t\t\t[\n\t\t\t\t\t\t'condition_id' => $condition_id,\n\t\t\t\t\t\t'min'          => $min,\n\t\t\t\t\t\t'max'          => $max,\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t\t'cost_per_order'   => (string) $i,\n\t\t\t\t'additional_costs' => [],\n\t\t\t\t'special_action'   => 'none',\n\t\t\t];\n\t\t}\n\n\t\treturn $rules;\n\t};\n\n\t$fixed_cost_rules = [\n\t\t[\n\t\t\t'conditions'       => [\n\t\t\t\t[\n\t\t\t\t\t'condition_id' => 'none',\n\t\t\t\t\t'min'          => '',\n\t\t\t\t\t'max'          => '',\n\t\t\t\t],\n\t\t\t],\n\t\t\t'cost_per_order'   => '50',\n\t\t\t'additional_costs' => [],\n\t\t\t'special_action'   => 'none',\n\t\t],\n\t];\n\n\t$weight_rules = $build_rules( 'weight' );\n\t$value_rules  = $build_rules( 'value' );\n\n\t$weight_method_id = $add_method( $zone, 'Weight based (Playground)', $weight_rules );\n\t$value_method_id  = $add_method( $zone, 'Order value based (Playground)', $value_rules );\n\t$fixed_method_id  = $add_method(\n\t\t$zone,\n\t\t'Fixed 50, free over 50 (Playground)',\n\t\t$fixed_cost_rules,\n\t\t[\n\t\t\t'method_free_shipping'             => '50',\n\t\t\t'method_free_shipping_label'       => 'Free',\n\t\t\t'method_free_shipping_cart_notice' => 'yes',\n\t\t]\n\t);\n\n\t$shop_page_id = function_exists( 'wc_get_page_id' ) ? (int) wc_get_page_id( 'shop' ) : 0;\n\tif ( $shop_page_id > 0 && $weight_method_id > 0 && $value_method_id > 0 && $fixed_method_id > 0 ) {\n\t\t$method_settings_url = static function ( $instance_id ) {\n\t\t\treturn admin_url( 'admin.php?page=wc-settings&tab=shipping&instance_id=' . $instance_id );\n\t\t};\n\n\t\t$shipping_methods_info = implode(\n\t\t\t\"\\n\",\n\t\t\t[\n\t\t\t\t'<section class=\"flexible-shipping-playground-guide\">',\n\t\t\t\t'<h2>Shipping methods configured for this demo</h2>',\n\t\t\t\t'<p>All methods are active in the Rest of the world shipping zone. Their costs are calculated independently, so you can compare them in the cart and checkout.</p>',\n\t\t\t\t'<ul>',\n\t\t\t\tsprintf(\n\t\t\t\t\t'<li><a href=\"%s\"><strong>Weight based (Playground)</strong></a> &mdash; the shipping cost matches the total cart weight: 1 kg costs $1, 2 kg costs $2, and so on up to 100 kg.</li>',\n\t\t\t\t\tesc_url( $method_settings_url( $weight_method_id ) )\n\t\t\t\t),\n\t\t\t\tsprintf(\n\t\t\t\t\t'<li><a href=\"%s\"><strong>Order value based (Playground)</strong></a> &mdash; the shipping cost matches the cart value: a $1 order costs $1 to ship, a $2 order costs $2, and so on up to $100.</li>',\n\t\t\t\t\tesc_url( $method_settings_url( $value_method_id ) )\n\t\t\t\t),\n\t\t\t\tsprintf(\n\t\t\t\t\t'<li><a href=\"%s\"><strong>Fixed 50, free over 50 (Playground)</strong></a> &mdash; shipping costs $50 below the threshold and becomes free when the cart reaches $50. The free shipping notice is enabled.</li>',\n\t\t\t\t\tesc_url( $method_settings_url( $fixed_method_id ) )\n\t\t\t\t),\n\t\t\t\t'</ul>',\n\t\t\t\t'</section>',\n\t\t\t]\n\t\t);\n\n\t\twp_update_post(\n\t\t\t[\n\t\t\t\t'ID'           => $shop_page_id,\n\t\t\t\t'post_content' => $shipping_methods_info,\n\t\t\t]\n\t\t);\n\t}\n}"
    }
  ]
}
