{
  "$schema": "https://playground.wordpress.net/blueprint-schema.json",
  "landingPage": "/restaurant-reservations",
  "preferredVersions": {
    "php": "8.3",
    "wp": "latest"
  },
  "phpExtensionBundles": ["kitchen-sink"],
  "features": {
    "networking": true
  },
  "steps": [
    {
      "step": "login",
      "username": "admin",
      "password": "password"
    },
    {
      "step": "setSiteOptions",
      "options": {
        "blogname": "Five Star Restaurant Reservations – WordPress Booking Plugin",
        "blogdescription": "A live preview of the Five Star Restaurant Reservations – WordPress Booking Plugin plugin"
      }
    },
    {
      "step": "installTheme",
      "themeData": {
        "resource": "wordpress.org/themes",
        "slug": "blocksy"
      },
      "options": {
        "activate": true
      }
    },
    {
      "step": "installPlugin",
      "options": {
        "activate": true
      },
      "pluginData": {
        "resource": "wordpress.org/plugins",
        "slug": "restaurant-reservations"
      }
    },
    {
      "step": "runPHP",
      "code": "<?php\nrequire_once '/wordpress/wp-load.php';\n\n$guests = array(\n  array('name' => 'John Smith', 'email' => 'john.smith@email.com', 'phone' => '555-0101', 'party' => 2),\n  array('name' => 'Sarah Johnson', 'email' => 'sarah.j@email.com', 'phone' => '555-0102', 'party' => 4),\n  array('name' => 'Michael Chen', 'email' => 'mchen@email.com', 'phone' => '555-0103', 'party' => 3),\n  array('name' => 'Emma Wilson', 'email' => 'emma.w@email.com', 'phone' => '555-0104', 'party' => 5),\n  array('name' => 'David Brown', 'email' => 'dbrown@email.com', 'phone' => '555-0105', 'party' => 2),\n  array('name' => 'Lisa Martinez', 'email' => 'lmartinez@email.com', 'phone' => '555-0106', 'party' => 6),\n  array('name' => 'James Anderson', 'email' => 'janderson@email.com', 'phone' => '555-0107', 'party' => 4),\n  array('name' => 'Rachel Taylor', 'email' => 'rtaylor@email.com', 'phone' => '555-0108', 'party' => 3),\n  array('name' => 'Christopher Lee', 'email' => 'clee@email.com', 'phone' => '555-0109', 'party' => 2),\n  array('name' => 'Amanda Garcia', 'email' => 'agarcia@email.com', 'phone' => '555-0110', 'party' => 5),\n);\n\n$bookings = array(\n  array('time' => '17:30:00', 'day_offset' => 0, 'status' => 'confirmed', 'guest_idx' => 0),\n  array('time' => '19:00:00', 'day_offset' => 0, 'status' => 'pending',   'guest_idx' => 1),\n  array('time' => '20:15:00', 'day_offset' => 0, 'status' => 'cancelled', 'guest_idx' => 2),\n  array('time' => '12:00:00', 'day_offset' => 0, 'status' => 'confirmed', 'guest_idx' => 3),\n  array('time' => '18:30:00', 'day_offset' => 1, 'status' => 'closed',    'guest_idx' => 4),\n  array('time' => '20:45:00', 'day_offset' => 1, 'status' => 'cancelled', 'guest_idx' => 5),\n  array('time' => '13:00:00', 'day_offset' => 1, 'status' => 'confirmed', 'guest_idx' => 6),\n  array('time' => '17:45:00', 'day_offset' => 2, 'status' => 'pending',   'guest_idx' => 7),\n  array('time' => '19:30:00', 'day_offset' => 2, 'status' => 'cancelled', 'guest_idx' => 8),\n  array('time' => '21:00:00', 'day_offset' => 2, 'status' => 'closed',    'guest_idx' => 9),\n);\n\n// Compute upcoming Friday date (day_offset 0=Fri, 1=Sat, 2=Sun)\n$today    = new DateTime('today');\n$dow      = (int)$today->format('N'); // 1=Mon … 7=Sun\n$days_to_friday = (5 - $dow + 7) % 7;\nif ($days_to_friday === 0) $days_to_friday = 7; // already Friday → next Friday\n$friday = clone $today;\n$friday->modify(\"+{$days_to_friday} days\");\n\nforeach ($bookings as $booking) {\n  $guest = $guests[$booking['guest_idx']];\n  $date_obj = clone $friday;\n  $date_obj->modify('+' . $booking['day_offset'] . ' days');\n  $date_str = $date_obj->format('Y-m-d') . ' ' . $booking['time'];\n\n  $post_id = wp_insert_post(array(\n    'post_title'        => $guest['name'],\n    'post_content'      => '',\n    'post_status'       => $booking['status'],\n    'post_type'         => 'rtb-booking',\n    'post_date'         => $date_str,\n    'post_date_gmt'     => $date_str,\n    'post_modified'     => $date_str,\n    'post_modified_gmt' => $date_str,\n    'post_author'       => 0,\n    'comment_status'    => 'closed',\n    'ping_status'       => 'closed',\n  ));\n\n  if ($post_id) {\n    $meta_value = array(\n      'party'             => $guest['party'],\n      'email'             => $guest['email'],\n      'phone'             => $guest['phone'],\n      'cancellation_code' => substr(bin2hex(random_bytes(5)), 0, 10),\n      'ip'                => '127.0.0.1',\n      'date_submission'   => (int)strtotime($date_str),\n      'confirmed_user'    => 1,\n    );\n    update_post_meta($post_id, 'rtb', $meta_value);\n  }\n}\n?>"
    },
    {
      "step": "writeFile",
      "path": "/wordpress/wp-content/mu-plugins/rtb-dynamic-dates.php",
      "data": "<?php\n/**\n * Keep dummy RTB bookings anchored to the upcoming Fri/Sat/Sun.\n * Runs once per day (transient-gated) on init.\n */\nadd_action('init', function() {\n  if (get_transient('rtb_dates_refreshed')) return;\n\n  $today       = new DateTime('today');\n  $dow         = (int)$today->format('N');\n  $days_to_fri = (5 - $dow + 7) % 7;\n  if ($days_to_fri === 0) $days_to_fri = 7;\n  $friday = clone $today;\n  $friday->modify(\"+{$days_to_fri} days\");\n\n  $time_slots = array(\n    array('17:30:00', 0), array('19:00:00', 0), array('20:15:00', 0), array('12:00:00', 0),\n    array('18:30:00', 1), array('20:45:00', 1), array('13:00:00', 1),\n    array('17:45:00', 2), array('19:30:00', 2), array('21:00:00', 2),\n  );\n\n  $posts = get_posts(array(\n    'post_type'   => 'rtb-booking',\n    'numberposts' => 10,\n    'orderby'     => 'ID',\n    'order'       => 'ASC',\n    'post_status' => array('confirmed','pending','cancelled','closed'),\n  ));\n\n  foreach ($posts as $i => $post) {\n    if (!isset($time_slots[$i])) continue;\n    list($time, $offset) = $time_slots[$i];\n    $d = clone $friday;\n    $d->modify(\"+{$offset} days\");\n    $new_date = $d->format('Y-m-d') . ' ' . $time;\n\n    wp_update_post(array(\n      'ID'                => $post->ID,\n      'post_date'         => $new_date,\n      'post_date_gmt'     => $new_date,\n      'post_modified'     => $new_date,\n      'post_modified_gmt' => $new_date,\n    ));\n\n    $meta = get_post_meta($post->ID, 'rtb', true) ?: array();\n    $meta['date_submission'] = (int)strtotime($new_date);\n    update_post_meta($post->ID, 'rtb', $meta);\n  }\n\n  set_transient('rtb_dates_refreshed', 1, DAY_IN_SECONDS);\n});\n"
    },
    {
      "step": "writeFile",
      "path": "/wordpress/wp-content/mu-plugins/custom-styles.php",
      "data": "<?php\nadd_action('wp_head', function() {\n  echo '<style>.rtb-booking-form label{margin-top: 50px;}\n\n/* ── Admin button ── */\n.view-admin-bookings{position:relative;font-size:13px;font-weight:500;color:#fff;background:#1a1a1a;text-decoration:none;border:none;border-radius:6px;padding:7px 16px;cursor:pointer;overflow:hidden;white-space:nowrap;transition:background .2s,transform .15s,box-shadow .2s;box-shadow:0 1px 2px rgba(0,0,0,.15);display:block;width:max-content;margin-top:10px}.view-admin-bookings:hover{background:#111;transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.25);color:#fff;text-decoration:none}.view-admin-bookings:active{transform:translateY(0);box-shadow:0 1px 3px rgba(0,0,0,.2)}\n\n/* ── Hero image: cap height + cover crop ── */\n.wp-block-image.alignfull{max-height:420px;overflow:hidden;display:flex;align-items:center}\n.wp-block-image.alignfull img{width:100%;height:420px;max-height:420px;object-fit:cover;object-position:center}\n\n/* ── RTB booking form – upscale restaurant redesign ── */\n@import url(\"https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600&family=Jost:wght@300;400;500&display=swap\");\n\n.rtb-booking-form{font-family:\"Jost\",sans-serif;font-weight:300;color:#2c2520;max-width:580px;margin:3rem auto;padding:0}\n\n/* View/cancel toggle */\n.rtb-modification-toggle{font-family:\"Jost\",sans-serif;font-size:12px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#8c7b6e;cursor:pointer;display:inline-block;padding-bottom:2px;border-bottom:1px solid #c9b9a8;margin-bottom:1.5rem;transition:color .2s,border-color .2s}\n.rtb-modification-toggle:hover{color:#2c2520;border-color:#2c2520}\n\n/* Modification search form */\n.rtb-modification-form{background:#faf7f4;border:1px solid #e4d9ce;border-radius:4px;padding:1.5rem;margin-bottom:2rem;font-size:14px}\n.rtb-modification-form>div{font-family:\"Cormorant Garamond\",serif;font-size:16px;color:#5c4a3a;margin-bottom:1rem}\n.rtb-modification-form label{display:block;font-size:12px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:#8c7b6e;margin-bottom:.75rem}\n.rtb-modification-form input[type=email],.rtb-modification-form input[type=text]{width:100%;box-sizing:border-box;border:0 none;border-bottom:1px solid #d4c5b5;background:transparent;padding:6px 0;font-family:\"Jost\",sans-serif;font-size:14px;font-weight:300;color:#2c2520;outline:none;transition:border-color .2s;margin-top:4px;display:block}\n.rtb-modification-form input:focus{border-bottom-color:#8c6a50}\n.rtb-find-reservation-button-div{margin-top:1.25rem}\n.rtb-find-reservation-button{display:inline-block;font-family:\"Jost\",sans-serif;font-size:12px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#fff;background:#2c2520;padding:9px 22px;border-radius:3px;cursor:pointer;transition:background .2s}\n.rtb-find-reservation-button:hover{background:#8c6a50}\n\n/* Main form */\n.rtb-booking-form-form{background:#fff;border:1px solid #e4d9ce}\n\n/* Fieldsets */\n.rtb-booking-form-form fieldset{border:none;margin:0;padding:2rem 2.25rem 1.5rem;border-bottom:1px solid #f0e8e0}\n.rtb-booking-form-form fieldset:last-of-type{border-bottom:none}\n.rtb-booking-form-form legend{font-family:\"Cormorant Garamond\",serif;font-size:21px;font-weight:500;color:#2c2520;letter-spacing:.02em;padding:0 0 .75rem;float:left;width:100%}\n\n/* Field rows */\n.rtb-booking-form-form .rtb-text,\n.rtb-booking-form-form .rtb-select,\n.rtb-booking-form-form .rtb-textarea{margin-bottom:1.25rem}\n\n/* Labels */\n.rtb-booking-form-form label{display:block;font-size:11px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#8c7b6e;margin-bottom:6px}\n\n/* Text / email / tel inputs */\n.rtb-booking-form-form input[type=text]:not(.picker__input),\n.rtb-booking-form-form input[type=email],\n.rtb-booking-form-form input[type=tel],.rtb-booking-form-form .picker__input{width:100%;box-sizing:border-box;border:none;border-bottom:1px solid #d4c5b5;background:transparent;padding:8px 0;font-family:\"Jost\",sans-serif;font-size:15px;font-weight:300;color:#2c2520;outline:none;transition:border-color .2s,box-shadow .2s;border-radius:0}\n.rtb-booking-form-form input[type=text]:focus,\n.rtb-booking-form-form input[type=email]:focus,\n.rtb-booking-form-form input[type=tel]:focus,.rtb-booking-form-form .picker__input:focus{border-bottom-color:#8c6a50;box-shadow:0 1px 0 #8c6a50}\n\n/* Select */\n.rtb-booking-form-form select{width:100%;box-sizing:border-box;border:none;border-bottom:1px solid #d4c5b5;background:transparent url(\"data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2710%27 height=%276%27%3E%3Cpath d=%27M0 0l5 6 5-6z%27 fill=%27%238c7b6e%27/%3E%3C/svg%3E\") no-repeat right 2px center;appearance:none;-webkit-appearance:none;padding:8px 20px 8px 0;font-family:\"Jost\",sans-serif;font-size:15px;font-weight:300;color:#2c2520;outline:none;border-radius:0;cursor:pointer;transition:border-color .2s}\n.rtb-booking-form-form select:focus{border-bottom-color:#8c6a50}\n\n/* Textarea */\n.rtb-booking-form-form textarea{width:100%;box-sizing:border-box;border:1px solid #d4c5b5;background:#faf7f4;padding:10px 12px;font-family:\"Jost\",sans-serif;font-size:14px;font-weight:300;color:#2c2520;outline:none;border-radius:3px;resize:vertical;min-height:80px;transition:border-color .2s}\n.rtb-booking-form-form textarea:focus{border-color:#8c6a50}\n\n/* Add message link */\n.add-message a{font-size:12px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:#8c7b6e;text-decoration:none;border-bottom:1px solid #c9b9a8;transition:color .2s}\n.add-message a:hover{color:#2c2520}\n\n/* Form footer / submit */\n.rtb-form-footer{background:#faf7f4;border-top:1px solid #e4d9ce;padding:1.5rem 2.25rem;}\n.rtb-form-submit button{font-family:\"Jost\",sans-serif;font-size:12px;font-weight:400;letter-spacing:.15em;text-transform:uppercase;color:#fff;background:#2c2520;border:none;padding:13px 36px;cursor:pointer;border-radius:3px;transition:background .25s,transform .15s}\n.rtb-form-submit button:hover{background:#8c6a50;transform:translateY(-1px)}\n.rtb-form-submit button:active{transform:translateY(0)}\n\n</style>';\n});\n"
    },
    {
      "step": "runPHP",
      "code": "<?php\nrequire_once '/wordpress/wp-load.php';\n$image_url = 'https://images.unsplash.com/photo-1634234498573-29224acf2907';\n$image_block = '<!-- wp:image {\"sizeSlug\":\"full\",\"linkDestination\":\"none\",\"align\":\"full\"} -->\n<figure class=\"wp-block-image alignfull size-full\"><img src=\"' . $image_url . '\" alt=\"Five Star Restaurant Reservations – WordPress Booking Plugin Banner\"/></figure>\n<!-- /wp:image -->';\n$text_content = '<!-- wp:group {\"style\":{\"spacing\":{\"padding\":{\"top\":\"2rem\",\"bottom\":\"2rem\",\"left\":\"2rem\",\"right\":\"2rem\"}}},\"layout\":{\"type\":\"constrained\"}} -->\n<div class=\"wp-block-group\" style=\"padding-top:2rem;padding-bottom:2rem;padding-left:2rem;padding-right:2rem\">\n<!-- wp:paragraph -->\n<p>Thank you for checking out our Five Star Restaurant Reservations – WordPress Booking Plugin plugin!</p>\n<!-- /wp:paragraph -->\n<!-- wp:paragraph -->\n<p>The [[booking-form]] shortcode is all you need to display your restaurant reservations booking form on your page — your customers can use it to place bookings for your restaurant.</p>\n<!-- /wp:paragraph -->\n<!-- wp:paragraph -->\n<p>You can control exactly what gets displayed to your customers from within the plugin settings.</p>\n<!-- /wp:paragraph -->\n<!-- wp:paragraph -->\n<p><a href=\"wp-admin/admin.php?page=rtb-bookings\" class=\"view-admin-bookings\">📋 View Admin Bookings Screen</a></p>\n<!-- /wp:paragraph -->\n<!-- wp:shortcode -->[booking-form]<!-- /wp:shortcode -->\n</div>\n<!-- /wp:group -->';\nwp_insert_post(array('post_title' => 'Restaurant Reservations','post_content' => $image_block . \"\\n\" . $text_content,'post_status' => 'publish','post_type' => 'page'));\n?>"
    },
    {
      "step": "writeFile",
      "path": "/wordpress/wp-content/mu-plugins/rtb-settings.php",
      "data": "<?php\nrequire_once '/wordpress/wp-load.php';\n$settings = array('schedule-open' => array(array('weekdays' => array('monday' => '1', 'tuesday' => '1', 'wednesday' => '1', 'thursday' => '1'), 'time' => array('start' => '5:00 PM', 'end' => '11:45 PM')), array('weekdays' => array('friday' => '1', 'saturday' => '1', 'sunday' => '1'), 'time' => array('start' => '11:00 AM', 'end' => '11:45 PM'))), 'schedule-closed' => array(array('date' => '2026/07/01'), array('date_range' => array('start' => '2026/08/02', 'end' => '2026/08/15'))), 'early-bookings' => '7', 'late-bookings' => '15', 'late-cancellations' => '60', 'date-onload' => 'soonest', 'time-interval' => '15', 'week-start' => '0', 'admin-ignore-schedule' => '1', 'booking-page' => 0, 'party-size-min' => '1', 'party-size' => '4', 'party-blank' => '1', 'auto-confirm-max-party-size' => '1', 'allow-cancellations' => '1', 'disable-cancellation-code-required' => '', 'show-cancelled-status' => '', 'require-phone' => '1', 'success-message' => '', 'confirmed-message' => '', 'pending-redirect-page' => '', 'confirmed-redirect-page' => '', 'cancelled-redirect-page' => '', 'i8n' => '', 'refresh-booking-listing' => '', 'date-format' => '', 'time-format' => '', 'display-unavailable-time-slots' => '', 'ban-emails' => '', 'ban-ips' => '', 'enable-captcha' => '', 'captcha-site-key' => '', 'captcha-secret-key' => '', 'disable-ip-capture' => '', 'require-consent' => '', 'consent-statement' => '', 'privacy-page' => 0, 'delete-data-days' => '');\nupdate_option('rtb-settings', $settings);\n"
    }
  ],
  "login": true
}
