Booking form
/**
* ============================================================
* INFINITELYCLEAR — BOOKING / SCHEDULING FORM (no plugin)
* ============================================================
* WHERE: WP Admin → Code Snippets → Add New (PHP snippet)
* Paste this WHOLE file → Save → Activate.
*
* WHAT IT GIVES YOU
* 1. A shortcode:
Book a Session
Choose your time with Kat
Pick the container, a preferred date, and a window that suits your day. Kat personally confirms the exact time within 24 hours — real back-and-forth, no apps, no accounts.
* Create a page “Book a Session” (slug: book-a-session),
* set Template = Default, add a “Shortcode” block with
*
Book a Session
Choose your time with Kat
Pick the container, a preferred date, and a window that suits your day. Kat personally confirms the exact time within 24 hours — real back-and-forth, no apps, no accounts.
* 2. A branded scheduling form: package picker (pre-selected
* from the link, e.g. /book-a-session/?package=deep-dive),
* preferred date + time window, contact details, notes.
* 3. On submit it:
* • emails the request to Kat,
* • adds the chosen package to the WooCommerce cart,
* • sends the customer straight to Checkout to pay.
* (If WooCommerce is off, it just shows a thank-you.)
*
* BUTTON LINKS FOR THE MENTORING PAGE
* /book-a-session/?package=lets-chat (Let’s Chat · $33)
* /book-a-session/?package=deep-dive (Deep-Dive · $97)
* /book-a-session/?package=mastermind (Mastermind · $297)
*
* CHANGE WHERE REQUESTS ARE EMAILED: edit ICBK_NOTIFY_EMAIL below.
* ============================================================
*/
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
/* —- SETTINGS ———————————————— */
define( ‘ICBK_NOTIFY_EMAIL’, ‘infinitelyclearshop@gmail.com’ ); // Kat’s inbox
/* —- PACKAGE MAP (slug → Woo product ID) ——————— */
function icbk_packages() {
return array(
‘lets-chat’ => array(
‘id’ => 652,
‘name’ => “Let’s Chat”,
‘meta’ => ’15 minutes · one focused question’,
‘price’ => 33,
),
‘deep-dive’ => array(
‘id’ => 656,
‘name’ => ‘Deep-Dive Session’,
‘meta’ => ’45 minutes · one stuck place, opened up’,
‘price’ => 97,
‘tag’ => ‘Most popular’,
),
‘mastermind’ => array(
‘id’ => 657,
‘name’ => ‘Monthly Mastermind’,
‘meta’ => ‘Ongoing monthly container with Kat’,
‘price’ => 297,
),
);
}
/* —- SHORTCODE ———————————————— */
add_shortcode( ‘ic_booking_form’, ‘icbk_render_form’ );
function icbk_render_form() {
$packages = icbk_packages();
/* pre-select from ?package=… (accepts slug or product ID) */
$pre = isset( $_GET[‘package’] ) ? sanitize_key( wp_unslash( $_GET[‘package’] ) ) : ”;
if ( $pre && ! isset( $packages[ $pre ] ) ) {
foreach ( $packages as $slug => $p ) {
if ( (string) $p[‘id’] === $pre ) { $pre = $slug; break; }
}
}
if ( ! isset( $packages[ $pre ] ) ) { $pre = ‘deep-dive’; }
$min_date = gmdate( ‘Y-m-d’, strtotime( ‘+1 day’ ) );
$booked = isset( $_GET[‘icbk’] ) && ‘thanks’ === $_GET[‘icbk’];
/* ———- confirmation state ———- */
if ( $booked ) {
return ‘
Request received.
Kat has your session request and will reply within 24 hours to
confirm the exact time. If your checkout is still open, completing payment
locks your session in.
‘ . icbk_css();
}
/* ———- form ———- */
$out = ‘
$out .= ‘
Book a Session
‘;
$out .= ‘
Choose your time with Kat
‘;
$out .= ‘
Pick the container, a preferred date, and a window that suits
your day. Kat personally confirms the exact time within 24 hours — real
back-and-forth, no apps, no accounts.
‘;
$out .= ‘
‘;
return $out . icbk_css();
}
/* —- STYLE —————————————————- */
function icbk_css() {
return “
“;
}
/* —- HANDLE SUBMIT ——————————————– */
add_action( ‘admin_post_ic_booking’, ‘icbk_handle’ );
add_action( ‘admin_post_nopriv_ic_booking’, ‘icbk_handle’ );
function icbk_handle() {
$back = home_url( ‘/book-a-session/’ );
/* honeypot: bots fill this */
if ( ! empty( $_POST[‘icbk_website’] ) ) {
wp_safe_redirect( add_query_arg( ‘icbk’, ‘thanks’, $back ) );
exit;
}
if ( ! isset( $_POST[‘icbk_nonce’] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[‘icbk_nonce’] ) ), ‘icbk_submit’ ) ) {
wp_safe_redirect( $back );
exit;
}
$packages = icbk_packages();
$slug = isset( $_POST[‘icbk_package’] ) ? sanitize_key( wp_unslash( $_POST[‘icbk_package’] ) ) : ”;
if ( ! isset( $packages[ $slug ] ) ) { $slug = ‘deep-dive’; }
$p = $packages[ $slug ];
$name = isset( $_POST[‘icbk_name’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_name’] ) ) : ”;
$email = isset( $_POST[‘icbk_email’] ) ? sanitize_email( wp_unslash( $_POST[‘icbk_email’] ) ) : ”;
$date = isset( $_POST[‘icbk_date’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_date’] ) ) : ”;
$win = isset( $_POST[‘icbk_window’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_window’] ) ) : ”;
$tz = isset( $_POST[‘icbk_tz’] ) ? sanitize_text_field( wp_unslash( $_POST[‘icbk_tz’] ) ) : ”;
$notes = isset( $_POST[‘icbk_notes’] ) ? sanitize_textarea_field( wp_unslash( $_POST[‘icbk_notes’] ) ) : ”;
if ( ! $name || ! is_email( $email ) || ! $date ) {
wp_safe_redirect( $back );
exit;
}
/* 1 · email the request to Kat */
$to = ICBK_NOTIFY_EMAIL;
$subject = ‘New session request — ‘ . $p[‘name’] . ‘ — ‘ . $name;
$body = “NEW SESSION REQUEST\n”
. str_repeat( ‘=’, 46 ) . “\n\n”
. ‘Container: ‘ . $p[‘name’] . ” ($” . number_format( $p[‘price’] ) . “)\n”
. ‘Preferred: ‘ . $date . ‘ · ‘ . $win . “\n”
. ‘Time zone: ‘ . ( $tz ? $tz : ‘not given’ ) . “\n\n”
. ‘Name: ‘ . $name . “\n”
. ‘Email: ‘ . $email . “\n\n”
. ‘Notes: ‘ . ( $notes ? $notes : ‘—’ ) . “\n\n”
. str_repeat( ‘-‘, 46 ) . “\n”
. ‘Reply directly to this email to confirm the time.’;
$headers = array( ‘Reply-To: ‘ . $name . ‘ <' . $email . '>‘ );
wp_mail( $to, $subject, $body, $headers );
/* 2 · gentle confirmation to the client */
$conf = “Hi ” . $name . “,\n\n”
. “Your request for a ” . $p[‘name’] . ” has landed with Kat.\n”
. “Preferred: ” . $date . ” · ” . $win . ( $tz ? ” (” . $tz . “)” : ” ) . “\n\n”
. “Kat will reply within 24 hours to confirm your exact time.\n”
. “Next step: complete checkout to lock your session in:\n”
. home_url( ‘/checkout/?add-to-cart=’ . $p[‘id’] ) . “\n\n”
. “— InfinitelyClear”;
wp_mail( $email, ‘Your session request — ‘ . $p[‘name’], $conf );
/* 3 · add to cart → checkout */
if ( function_exists( ‘WC’ ) && WC()->cart && wc_get_product( $p[‘id’] ) && wc_get_product( $p[‘id’] )->is_purchasable() ) {
WC()->cart->empty_cart();
WC()->cart->add_to_cart( $p[‘id’], 1 );
wp_safe_redirect( wc_get_checkout_url() );
exit;
}
/* Woo missing/unpurchasable → thank-you state */
wp_safe_redirect( add_query_arg( ‘icbk’, ‘thanks’, $back ) );
exit;
}