Autosave: 20260324-103828
This commit is contained in:
parent
a63b4710db
commit
fd386cfdd5
24
.htaccess
24
.htaccess
@ -1,18 +1,10 @@
|
|||||||
DirectoryIndex index.php index.html
|
# BEGIN WordPress
|
||||||
Options -Indexes
|
<IfModule mod_rewrite.c>
|
||||||
Options -MultiViews
|
|
||||||
|
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
|
RewriteBase /
|
||||||
# 0) Serve existing files/directories as-is
|
RewriteRule ^index\.php$ - [L]
|
||||||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteCond %{REQUEST_FILENAME} -d
|
|
||||||
RewriteRule ^ - [L]
|
|
||||||
|
|
||||||
# 1) Internal map: /page or /page/ -> /page.php (if such PHP file exists)
|
|
||||||
RewriteCond %{REQUEST_FILENAME}.php -f
|
|
||||||
RewriteRule ^(.+?)/?$ $1.php [L]
|
|
||||||
|
|
||||||
# 2) Optional: strip trailing slash for non-directories (keeps .php links working)
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
RewriteRule ^(.+)/$ $1 [R=301,L]
|
RewriteRule . /index.php [L]
|
||||||
|
</IfModule>
|
||||||
|
# END WordPress
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
WordPress Admin Credentials:
|
WordPress Admin Credentials:
|
||||||
URL: http://localhost/wp-admin
|
URL: http://localhost/wp-admin
|
||||||
Username: admin
|
Username: admin
|
||||||
Password: c59u3v2geHuIQMRP
|
Password: qhpYYAHPC3qKPM9vB7
|
||||||
|
|||||||
BIN
assets/pasted-20260324-101557-c305dc01.jpg
Normal file
BIN
assets/pasted-20260324-101557-c305dc01.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
assets/vm-shot-2026-03-24T10-15-21-681Z.jpg
Normal file
BIN
assets/vm-shot-2026-03-24T10-15-21-681Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
1626
wp-content/mu-plugins/coaching-mvp.php
Normal file
1626
wp-content/mu-plugins/coaching-mvp.php
Normal file
File diff suppressed because it is too large
Load Diff
842
wp-content/mu-plugins/coaching-mvp.php.bak-20260324
Normal file
842
wp-content/mu-plugins/coaching-mvp.php.bak-20260324
Normal file
@ -0,0 +1,842 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: Coaching MVP Site Kit
|
||||||
|
* Description: Registers testimonials, bookings, and lead capture workflow plus frontend styles for the coaching MVP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_services() {
|
||||||
|
return [
|
||||||
|
'discovery-call' => 'Discovery Call',
|
||||||
|
'clarity-session' => 'Clarity Session',
|
||||||
|
'momentum-coaching' => 'Momentum Coaching',
|
||||||
|
'leadership-intensives' => 'Leadership Intensive',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_register_post_types() {
|
||||||
|
register_post_type('testimonial', [
|
||||||
|
'labels' => [
|
||||||
|
'name' => 'Testimonials',
|
||||||
|
'singular_name' => 'Testimonial',
|
||||||
|
'add_new_item' => 'Add New Testimonial',
|
||||||
|
'edit_item' => 'Edit Testimonial',
|
||||||
|
],
|
||||||
|
'public' => true,
|
||||||
|
'show_in_rest' => true,
|
||||||
|
'menu_icon' => 'dashicons-format-quote',
|
||||||
|
'supports' => ['title', 'editor', 'excerpt'],
|
||||||
|
'has_archive' => false,
|
||||||
|
'rewrite' => ['slug' => 'testimonial'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_post_type('booking_request', [
|
||||||
|
'labels' => [
|
||||||
|
'name' => 'Bookings',
|
||||||
|
'singular_name' => 'Booking',
|
||||||
|
'add_new_item' => 'Add Booking',
|
||||||
|
'edit_item' => 'View Booking',
|
||||||
|
],
|
||||||
|
'public' => false,
|
||||||
|
'show_ui' => true,
|
||||||
|
'show_in_rest' => false,
|
||||||
|
'menu_icon' => 'dashicons-calendar-alt',
|
||||||
|
'supports' => ['title'],
|
||||||
|
'capability_type' => 'post',
|
||||||
|
'map_meta_cap' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
register_post_type('lead_capture', [
|
||||||
|
'labels' => [
|
||||||
|
'name' => 'Leads',
|
||||||
|
'singular_name' => 'Lead',
|
||||||
|
'add_new_item' => 'Add Lead',
|
||||||
|
'edit_item' => 'View Lead',
|
||||||
|
],
|
||||||
|
'public' => false,
|
||||||
|
'show_ui' => true,
|
||||||
|
'show_in_rest' => false,
|
||||||
|
'menu_icon' => 'dashicons-email-alt2',
|
||||||
|
'supports' => ['title'],
|
||||||
|
'capability_type' => 'post',
|
||||||
|
'map_meta_cap' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
add_action('init', 'coaching_mvp_register_post_types');
|
||||||
|
|
||||||
|
function coaching_mvp_body_class($classes) {
|
||||||
|
$classes[] = 'coaching-mvp-active';
|
||||||
|
return $classes;
|
||||||
|
}
|
||||||
|
add_filter('body_class', 'coaching_mvp_body_class');
|
||||||
|
|
||||||
|
function coaching_mvp_styles() {
|
||||||
|
if (is_admin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_register_style('coaching-mvp-inline', false, [], null);
|
||||||
|
wp_enqueue_style('coaching-mvp-inline');
|
||||||
|
|
||||||
|
$css = <<<'CSS'
|
||||||
|
:root {
|
||||||
|
--coach-primary: #5b6cff;
|
||||||
|
--coach-secondary: #16c4b5;
|
||||||
|
--coach-background: #f4f7ff;
|
||||||
|
--coach-surface: #ffffff;
|
||||||
|
--coach-text: #172033;
|
||||||
|
--coach-muted: #5f6b84;
|
||||||
|
--coach-border: rgba(23,32,51,.08);
|
||||||
|
--coach-shadow: 0 30px 70px rgba(32,45,91,.14);
|
||||||
|
--coach-radius: 24px;
|
||||||
|
--coach-radius-sm: 16px;
|
||||||
|
--coach-spacing: 1.5rem;
|
||||||
|
}
|
||||||
|
body.coaching-mvp-active {
|
||||||
|
background: linear-gradient(180deg, #eef3ff 0%, #f9fbff 32%, #ffffff 100%);
|
||||||
|
color: var(--coach-text);
|
||||||
|
}
|
||||||
|
body.coaching-mvp-active .wp-site-blocks,
|
||||||
|
body.coaching-mvp-active .site,
|
||||||
|
body.coaching-mvp-active main {
|
||||||
|
color: var(--coach-text);
|
||||||
|
}
|
||||||
|
body.coaching-mvp-active.page .wp-site-blocks main,
|
||||||
|
body.coaching-mvp-active.home .wp-site-blocks main,
|
||||||
|
body.coaching-mvp-active.blog .wp-site-blocks main {
|
||||||
|
--wp--style--global--content-size: min(1180px, calc(100vw - 48px));
|
||||||
|
--wp--style--global--wide-size: min(1320px, calc(100vw - 48px));
|
||||||
|
}
|
||||||
|
body.coaching-mvp-active.page .wp-block-post-content,
|
||||||
|
body.coaching-mvp-active.home .wp-block-post-content,
|
||||||
|
body.coaching-mvp-active.blog .wp-block-post-content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
body.coaching-mvp-active .wp-block-post-content.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
|
||||||
|
body.coaching-mvp-active .coach-home-page.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
|
||||||
|
max-width: var(--wp--style--global--content-size);
|
||||||
|
}
|
||||||
|
.coach-hero,
|
||||||
|
.coach-section,
|
||||||
|
.coach-panel,
|
||||||
|
.coach-form-wrap,
|
||||||
|
.coach-service-card,
|
||||||
|
.coach-testimonial-card,
|
||||||
|
.coach-stat,
|
||||||
|
.coach-process-card,
|
||||||
|
.coach-mini-card,
|
||||||
|
.coach-faq-card,
|
||||||
|
.coach-story-card {
|
||||||
|
border-radius: var(--coach-radius);
|
||||||
|
}
|
||||||
|
.coach-hero {
|
||||||
|
padding: clamp(2rem, 5vw, 4rem);
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at top right, rgba(22,196,181,.28), transparent 28%),
|
||||||
|
radial-gradient(circle at bottom left, rgba(91,108,255,.20), transparent 32%),
|
||||||
|
linear-gradient(135deg, #101a3a 0%, #213872 48%, #5b6cff 100%);
|
||||||
|
box-shadow: var(--coach-shadow);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.coach-hero h1,
|
||||||
|
.coach-hero p,
|
||||||
|
.coach-hero li,
|
||||||
|
.coach-hero strong {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.coach-eyebrow {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .5rem;
|
||||||
|
padding: .45rem .9rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(255,255,255,.12);
|
||||||
|
border: 1px solid rgba(255,255,255,.18);
|
||||||
|
font-size: .82rem;
|
||||||
|
letter-spacing: .06em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.coach-hero .wp-block-buttons .wp-block-button__link,
|
||||||
|
.coach-cta-row .wp-block-button__link,
|
||||||
|
.coach-form-wrap button,
|
||||||
|
.coach-inline-link {
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: .95rem 1.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.coach-hero .is-style-outline > .wp-block-button__link {
|
||||||
|
border: 1px solid rgba(255,255,255,.45);
|
||||||
|
color: #fff;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.coach-grid-2,
|
||||||
|
.coach-grid-3,
|
||||||
|
.coach-grid-4,
|
||||||
|
.coach-card-grid,
|
||||||
|
.coach-testimonial-grid,
|
||||||
|
.coach-process-grid,
|
||||||
|
.coach-story-grid,
|
||||||
|
.coach-faq-grid,
|
||||||
|
.coach-stats-grid,
|
||||||
|
.coach-mini-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.2rem;
|
||||||
|
}
|
||||||
|
.coach-grid-2 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
|
||||||
|
.coach-grid-3,
|
||||||
|
.coach-card-grid,
|
||||||
|
.coach-testimonial-grid,
|
||||||
|
.coach-process-grid,
|
||||||
|
.coach-story-grid,
|
||||||
|
.coach-faq-grid,
|
||||||
|
.coach-mini-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
|
||||||
|
.coach-grid-4,
|
||||||
|
.coach-stats-grid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
|
||||||
|
.coach-panel,
|
||||||
|
.coach-service-card,
|
||||||
|
.coach-testimonial-card,
|
||||||
|
.coach-stat,
|
||||||
|
.coach-process-card,
|
||||||
|
.coach-mini-card,
|
||||||
|
.coach-faq-card,
|
||||||
|
.coach-story-card,
|
||||||
|
.coach-form-wrap {
|
||||||
|
background: rgba(255,255,255,.92);
|
||||||
|
border: 1px solid var(--coach-border);
|
||||||
|
box-shadow: var(--coach-shadow);
|
||||||
|
padding: 1.35rem;
|
||||||
|
}
|
||||||
|
.coach-panel.soft {
|
||||||
|
background: rgba(255,255,255,.10);
|
||||||
|
border-color: rgba(255,255,255,.16);
|
||||||
|
}
|
||||||
|
.coach-stat strong {
|
||||||
|
display: block;
|
||||||
|
font-size: clamp(1.45rem, 3vw, 2.1rem);
|
||||||
|
color: var(--coach-text);
|
||||||
|
}
|
||||||
|
.coach-stat span,
|
||||||
|
.coach-muted,
|
||||||
|
.coach-service-card p,
|
||||||
|
.coach-process-card p,
|
||||||
|
.coach-faq-card p,
|
||||||
|
.coach-story-card p,
|
||||||
|
.coach-testimonial-meta,
|
||||||
|
.coach-form-wrap p,
|
||||||
|
.coach-section p {
|
||||||
|
color: var(--coach-muted);
|
||||||
|
}
|
||||||
|
.coach-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .45rem;
|
||||||
|
padding: .4rem .8rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(91,108,255,.10);
|
||||||
|
color: var(--coach-primary);
|
||||||
|
font-size: .85rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.coach-service-card h3,
|
||||||
|
.coach-process-card h3,
|
||||||
|
.coach-faq-card h3,
|
||||||
|
.coach-story-card h3,
|
||||||
|
.coach-testimonial-card h3,
|
||||||
|
.coach-mini-card h3 {
|
||||||
|
margin-top: .35rem;
|
||||||
|
margin-bottom: .55rem;
|
||||||
|
}
|
||||||
|
.coach-service-card ul,
|
||||||
|
.coach-process-card ul,
|
||||||
|
.coach-story-card ul {
|
||||||
|
margin: .8rem 0 0 1rem;
|
||||||
|
}
|
||||||
|
.coach-icon-dot {
|
||||||
|
width: 2.25rem;
|
||||||
|
height: 2.25rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(91,108,255,.12);
|
||||||
|
color: var(--coach-primary);
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
.coach-form-wrap {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
.coach-form-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.coach-form-grid .full {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
.coach-form-wrap label {
|
||||||
|
display: block;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: .4rem;
|
||||||
|
color: var(--coach-text);
|
||||||
|
}
|
||||||
|
.coach-form-wrap input,
|
||||||
|
.coach-form-wrap textarea,
|
||||||
|
.coach-form-wrap select {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid rgba(23,32,51,.12);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: .9rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
background: #fff;
|
||||||
|
color: var(--coach-text);
|
||||||
|
}
|
||||||
|
.coach-form-wrap textarea {
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
.coach-form-wrap button {
|
||||||
|
border: 0;
|
||||||
|
background: linear-gradient(135deg, var(--coach-primary), #7f56d9);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 12px 24px rgba(91,108,255,.25);
|
||||||
|
}
|
||||||
|
.coach-alert {
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: .95rem 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.coach-alert.success {
|
||||||
|
background: rgba(22,196,181,.12);
|
||||||
|
color: #116c63;
|
||||||
|
border: 1px solid rgba(22,196,181,.18);
|
||||||
|
}
|
||||||
|
.coach-alert.error {
|
||||||
|
background: rgba(255,107,129,.10);
|
||||||
|
color: #8d2d3b;
|
||||||
|
border: 1px solid rgba(255,107,129,.18);
|
||||||
|
}
|
||||||
|
.coach-testimonial-grid blockquote {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.coach-testimonial-card .coach-rating {
|
||||||
|
color: #f5a524;
|
||||||
|
letter-spacing: .18em;
|
||||||
|
font-size: .95rem;
|
||||||
|
}
|
||||||
|
.coach-cta-band {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: linear-gradient(135deg, rgba(91,108,255,.12), rgba(22,196,181,.12));
|
||||||
|
border: 1px solid rgba(91,108,255,.12);
|
||||||
|
border-radius: var(--coach-radius);
|
||||||
|
}
|
||||||
|
.coach-stack > * + * {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
.coach-section {
|
||||||
|
margin-top: clamp(1.4rem, 4vw, 2.5rem);
|
||||||
|
}
|
||||||
|
.coach-home-page .wp-block-post-title,
|
||||||
|
.page-slug-home .wp-block-post-title {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.coach-inline-link {
|
||||||
|
color: var(--coach-primary);
|
||||||
|
background: rgba(91,108,255,.08);
|
||||||
|
}
|
||||||
|
.coach-admin-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .5rem;
|
||||||
|
margin-top: .6rem;
|
||||||
|
color: var(--coach-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.coach-footer-note {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--coach-muted);
|
||||||
|
font-size: .95rem;
|
||||||
|
}
|
||||||
|
@media (max-width: 781px) {
|
||||||
|
.coach-hero { padding: 1.5rem; }
|
||||||
|
}
|
||||||
|
CSS;
|
||||||
|
|
||||||
|
wp_add_inline_style('coaching-mvp-inline', $css);
|
||||||
|
}
|
||||||
|
add_action('wp_enqueue_scripts', 'coaching_mvp_styles');
|
||||||
|
|
||||||
|
function coaching_mvp_sanitize_textarea($value) {
|
||||||
|
return trim(wp_strip_all_tags((string) $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_handle_forms() {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || empty($_POST['coaching_form_action'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = sanitize_key(wp_unslash($_POST['coaching_form_action']));
|
||||||
|
$redirect = !empty($_POST['_wp_http_referer']) ? wp_unslash($_POST['_wp_http_referer']) : home_url('/');
|
||||||
|
$redirect = remove_query_arg(['booking_status', 'lead_status'], $redirect);
|
||||||
|
|
||||||
|
if (!isset($_POST['coaching_form_nonce']) || !wp_verify_nonce(wp_unslash($_POST['coaching_form_nonce']), 'coaching_form_submit')) {
|
||||||
|
wp_safe_redirect(add_query_arg($action === 'booking' ? 'booking_status' : 'lead_status', 'error', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = sanitize_text_field(wp_unslash($_POST['name'] ?? ''));
|
||||||
|
$email = sanitize_email(wp_unslash($_POST['email'] ?? ''));
|
||||||
|
$phone = sanitize_text_field(wp_unslash($_POST['phone'] ?? ''));
|
||||||
|
$message = coaching_mvp_sanitize_textarea(wp_unslash($_POST['message'] ?? ''));
|
||||||
|
|
||||||
|
if (!$name || !$email) {
|
||||||
|
wp_safe_redirect(add_query_arg($action === 'booking' ? 'booking_status' : 'lead_status', 'error', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'booking') {
|
||||||
|
$service = sanitize_text_field(wp_unslash($_POST['service'] ?? 'Discovery Call'));
|
||||||
|
$preferred_date = sanitize_text_field(wp_unslash($_POST['preferred_date'] ?? ''));
|
||||||
|
$preferred_time = sanitize_text_field(wp_unslash($_POST['preferred_time'] ?? ''));
|
||||||
|
$format = sanitize_text_field(wp_unslash($_POST['session_format'] ?? 'Zoom'));
|
||||||
|
$goal = coaching_mvp_sanitize_textarea(wp_unslash($_POST['goal'] ?? ''));
|
||||||
|
$post_id = wp_insert_post([
|
||||||
|
'post_type' => 'booking_request',
|
||||||
|
'post_status' => 'private',
|
||||||
|
'post_title' => sprintf('%s — %s', $name, $preferred_date ?: current_time('Y-m-d')),
|
||||||
|
], true);
|
||||||
|
if (is_wp_error($post_id)) {
|
||||||
|
wp_safe_redirect(add_query_arg('booking_status', 'error', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
update_post_meta($post_id, '_booking_name', $name);
|
||||||
|
update_post_meta($post_id, '_booking_email', $email);
|
||||||
|
update_post_meta($post_id, '_booking_phone', $phone);
|
||||||
|
update_post_meta($post_id, '_booking_service', $service);
|
||||||
|
update_post_meta($post_id, '_booking_date', $preferred_date);
|
||||||
|
update_post_meta($post_id, '_booking_time', $preferred_time);
|
||||||
|
update_post_meta($post_id, '_booking_format', $format);
|
||||||
|
update_post_meta($post_id, '_booking_goal', $goal);
|
||||||
|
update_post_meta($post_id, '_booking_message', $message);
|
||||||
|
wp_safe_redirect(add_query_arg('booking_status', 'success', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'lead') {
|
||||||
|
$focus = sanitize_text_field(wp_unslash($_POST['focus'] ?? ''));
|
||||||
|
$company = sanitize_text_field(wp_unslash($_POST['company'] ?? ''));
|
||||||
|
$post_id = wp_insert_post([
|
||||||
|
'post_type' => 'lead_capture',
|
||||||
|
'post_status' => 'private',
|
||||||
|
'post_title' => sprintf('%s — %s', $name, current_time('Y-m-d H:i')),
|
||||||
|
], true);
|
||||||
|
if (is_wp_error($post_id)) {
|
||||||
|
wp_safe_redirect(add_query_arg('lead_status', 'error', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
update_post_meta($post_id, '_lead_name', $name);
|
||||||
|
update_post_meta($post_id, '_lead_email', $email);
|
||||||
|
update_post_meta($post_id, '_lead_phone', $phone);
|
||||||
|
update_post_meta($post_id, '_lead_company', $company);
|
||||||
|
update_post_meta($post_id, '_lead_focus', $focus);
|
||||||
|
update_post_meta($post_id, '_lead_message', $message);
|
||||||
|
wp_safe_redirect(add_query_arg('lead_status', 'success', $redirect));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action('init', 'coaching_mvp_handle_forms', 20);
|
||||||
|
|
||||||
|
function coaching_mvp_booking_form_shortcode() {
|
||||||
|
$status = isset($_GET['booking_status']) ? sanitize_key(wp_unslash($_GET['booking_status'])) : '';
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<div class="coach-form-wrap" id="book-form">
|
||||||
|
<?php if ($status === 'success') : ?>
|
||||||
|
<div class="coach-alert success">Thanks — your booking request was received. You can review it anytime in the WordPress admin under Bookings.</div>
|
||||||
|
<?php elseif ($status === 'error') : ?>
|
||||||
|
<div class="coach-alert error">Please complete the required fields and try again.</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="coach-stack">
|
||||||
|
<div>
|
||||||
|
<span class="coach-badge">Book a pay-later session</span>
|
||||||
|
<h3>Request your coaching session</h3>
|
||||||
|
<p>Pick the service, preferred date, and format. This MVP stores requests in WordPress so the coach can confirm details personally.</p>
|
||||||
|
</div>
|
||||||
|
<form method="post" class="coach-stack">
|
||||||
|
<?php wp_nonce_field('coaching_form_submit', 'coaching_form_nonce'); ?>
|
||||||
|
<input type="hidden" name="coaching_form_action" value="booking" />
|
||||||
|
<div class="coach-form-grid">
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-name">Full name</label>
|
||||||
|
<input id="coach-book-name" type="text" name="name" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-email">Email</label>
|
||||||
|
<input id="coach-book-email" type="email" name="email" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-phone">Phone</label>
|
||||||
|
<input id="coach-book-phone" type="text" name="phone" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-service">Service</label>
|
||||||
|
<select id="coach-book-service" name="service">
|
||||||
|
<?php foreach (coaching_mvp_services() as $value => $label) : ?>
|
||||||
|
<option value="<?php echo esc_attr($label); ?>"><?php echo esc_html($label); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-date">Preferred date</label>
|
||||||
|
<input id="coach-book-date" type="date" name="preferred_date" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-time">Preferred time</label>
|
||||||
|
<input id="coach-book-time" type="time" name="preferred_time" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-book-format">Session format</label>
|
||||||
|
<select id="coach-book-format" name="session_format">
|
||||||
|
<option value="Zoom">Zoom</option>
|
||||||
|
<option value="Phone">Phone</option>
|
||||||
|
<option value="In Person">In Person</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="full">
|
||||||
|
<label for="coach-book-goal">What would you like help with?</label>
|
||||||
|
<textarea id="coach-book-goal" name="goal" placeholder="Share the goal, transition, challenge, or outcome you want to focus on."></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="full">
|
||||||
|
<label for="coach-book-message">Anything else?</label>
|
||||||
|
<textarea id="coach-book-message" name="message" placeholder="Include timing constraints, preferred cadence, or context."></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit">Request Session</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
add_shortcode('coaching_booking_form', 'coaching_mvp_booking_form_shortcode');
|
||||||
|
|
||||||
|
function coaching_mvp_lead_form_shortcode() {
|
||||||
|
$status = isset($_GET['lead_status']) ? sanitize_key(wp_unslash($_GET['lead_status'])) : '';
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<div class="coach-form-wrap" id="lead-form">
|
||||||
|
<?php if ($status === 'success') : ?>
|
||||||
|
<div class="coach-alert success">Thanks — your message was captured and is now visible in the WordPress admin under Leads.</div>
|
||||||
|
<?php elseif ($status === 'error') : ?>
|
||||||
|
<div class="coach-alert error">Please add your name and email so we can respond properly.</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="coach-stack">
|
||||||
|
<div>
|
||||||
|
<span class="coach-badge">Lead capture</span>
|
||||||
|
<h3>Start the conversation</h3>
|
||||||
|
<p>Not ready to book yet? Share your focus area and the coach can follow up with the right next step.</p>
|
||||||
|
</div>
|
||||||
|
<form method="post" class="coach-stack">
|
||||||
|
<?php wp_nonce_field('coaching_form_submit', 'coaching_form_nonce'); ?>
|
||||||
|
<input type="hidden" name="coaching_form_action" value="lead" />
|
||||||
|
<div class="coach-form-grid">
|
||||||
|
<div>
|
||||||
|
<label for="coach-lead-name">Full name</label>
|
||||||
|
<input id="coach-lead-name" type="text" name="name" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-lead-email">Email</label>
|
||||||
|
<input id="coach-lead-email" type="email" name="email" required />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-lead-phone">Phone</label>
|
||||||
|
<input id="coach-lead-phone" type="text" name="phone" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="coach-lead-company">Company / role</label>
|
||||||
|
<input id="coach-lead-company" type="text" name="company" />
|
||||||
|
</div>
|
||||||
|
<div class="full">
|
||||||
|
<label for="coach-lead-focus">What are you working toward?</label>
|
||||||
|
<input id="coach-lead-focus" type="text" name="focus" placeholder="Examples: career transition, executive presence, consistency, burnout recovery" />
|
||||||
|
</div>
|
||||||
|
<div class="full">
|
||||||
|
<label for="coach-lead-message">Message</label>
|
||||||
|
<textarea id="coach-lead-message" name="message" placeholder="Share what support would feel most valuable right now."></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="submit">Send Inquiry</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
add_shortcode('coaching_lead_form', 'coaching_mvp_lead_form_shortcode');
|
||||||
|
|
||||||
|
function coaching_mvp_testimonials_shortcode($atts = []) {
|
||||||
|
$atts = shortcode_atts(['limit' => 6], $atts, 'coaching_testimonials');
|
||||||
|
$items = get_posts([
|
||||||
|
'post_type' => 'testimonial',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'numberposts' => (int) $atts['limit'],
|
||||||
|
'orderby' => 'menu_order date',
|
||||||
|
'order' => 'ASC',
|
||||||
|
]);
|
||||||
|
if (!$items) {
|
||||||
|
return '<p>No testimonials yet.</p>';
|
||||||
|
}
|
||||||
|
ob_start();
|
||||||
|
echo '<div class="coach-testimonial-grid">';
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$role = get_post_meta($item->ID, '_testimonial_role', true);
|
||||||
|
echo '<article class="coach-testimonial-card">';
|
||||||
|
echo '<div class="coach-rating">★★★★★</div>';
|
||||||
|
echo '<blockquote><p>' . esc_html(wp_strip_all_tags($item->post_content)) . '</p></blockquote>';
|
||||||
|
echo '<h3>' . esc_html(get_the_title($item)) . '</h3>';
|
||||||
|
if ($role) {
|
||||||
|
echo '<div class="coach-testimonial-meta">' . esc_html($role) . '</div>';
|
||||||
|
}
|
||||||
|
echo '</article>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
add_shortcode('coaching_testimonials', 'coaching_mvp_testimonials_shortcode');
|
||||||
|
|
||||||
|
function coaching_mvp_admin_columns($columns, $post_type) {
|
||||||
|
if ($post_type === 'booking_request') {
|
||||||
|
return [
|
||||||
|
'cb' => $columns['cb'],
|
||||||
|
'title' => 'Booking',
|
||||||
|
'service' => 'Service',
|
||||||
|
'date' => 'Date',
|
||||||
|
'contact' => 'Contact',
|
||||||
|
'format' => 'Format',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if ($post_type === 'lead_capture') {
|
||||||
|
return [
|
||||||
|
'cb' => $columns['cb'],
|
||||||
|
'title' => 'Lead',
|
||||||
|
'focus' => 'Focus',
|
||||||
|
'contact' => 'Contact',
|
||||||
|
'date' => 'Received',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if ($post_type === 'testimonial') {
|
||||||
|
$columns['role'] = 'Role';
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
add_filter('manage_booking_request_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'booking_request'));
|
||||||
|
add_filter('manage_lead_capture_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'lead_capture'));
|
||||||
|
add_filter('manage_testimonial_posts_columns', fn($columns) => coaching_mvp_admin_columns($columns, 'testimonial'));
|
||||||
|
|
||||||
|
function coaching_mvp_render_admin_column($column, $post_id) {
|
||||||
|
switch ($column) {
|
||||||
|
case 'service':
|
||||||
|
echo esc_html((string) get_post_meta($post_id, '_booking_service', true));
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
if (get_post_type($post_id) === 'booking_request') {
|
||||||
|
$date = get_post_meta($post_id, '_booking_date', true);
|
||||||
|
$time = get_post_meta($post_id, '_booking_time', true);
|
||||||
|
echo esc_html(trim($date . ' ' . $time));
|
||||||
|
} else {
|
||||||
|
echo esc_html(get_the_date('Y-m-d H:i', $post_id));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'contact':
|
||||||
|
$email_key = get_post_type($post_id) === 'booking_request' ? '_booking_email' : '_lead_email';
|
||||||
|
$phone_key = get_post_type($post_id) === 'booking_request' ? '_booking_phone' : '_lead_phone';
|
||||||
|
echo esc_html((string) get_post_meta($post_id, $email_key, true));
|
||||||
|
$phone = get_post_meta($post_id, $phone_key, true);
|
||||||
|
if ($phone) {
|
||||||
|
echo '<br>' . esc_html((string) $phone);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'format':
|
||||||
|
echo esc_html((string) get_post_meta($post_id, '_booking_format', true));
|
||||||
|
break;
|
||||||
|
case 'focus':
|
||||||
|
echo esc_html((string) get_post_meta($post_id, '_lead_focus', true));
|
||||||
|
break;
|
||||||
|
case 'role':
|
||||||
|
echo esc_html((string) get_post_meta($post_id, '_testimonial_role', true));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action('manage_booking_request_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
|
||||||
|
add_action('manage_lead_capture_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
|
||||||
|
add_action('manage_testimonial_posts_custom_column', 'coaching_mvp_render_admin_column', 10, 2);
|
||||||
|
|
||||||
|
function coaching_mvp_details_meta_box() {
|
||||||
|
foreach (['booking_request', 'lead_capture'] as $post_type) {
|
||||||
|
add_meta_box('coaching-mvp-details', 'Submission Details', 'coaching_mvp_details_meta_box_html', $post_type, 'normal', 'high');
|
||||||
|
}
|
||||||
|
add_meta_box('coaching-mvp-testimonial-role', 'Testimonial Details', 'coaching_mvp_testimonial_meta_box_html', 'testimonial', 'side');
|
||||||
|
}
|
||||||
|
add_action('add_meta_boxes', 'coaching_mvp_details_meta_box');
|
||||||
|
|
||||||
|
function coaching_mvp_details_meta_box_html($post) {
|
||||||
|
if ($post->post_type === 'booking_request') {
|
||||||
|
$fields = [
|
||||||
|
'Name' => get_post_meta($post->ID, '_booking_name', true),
|
||||||
|
'Email' => get_post_meta($post->ID, '_booking_email', true),
|
||||||
|
'Phone' => get_post_meta($post->ID, '_booking_phone', true),
|
||||||
|
'Service' => get_post_meta($post->ID, '_booking_service', true),
|
||||||
|
'Preferred date' => get_post_meta($post->ID, '_booking_date', true),
|
||||||
|
'Preferred time' => get_post_meta($post->ID, '_booking_time', true),
|
||||||
|
'Format' => get_post_meta($post->ID, '_booking_format', true),
|
||||||
|
'Goal' => get_post_meta($post->ID, '_booking_goal', true),
|
||||||
|
'Extra notes' => get_post_meta($post->ID, '_booking_message', true),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$fields = [
|
||||||
|
'Name' => get_post_meta($post->ID, '_lead_name', true),
|
||||||
|
'Email' => get_post_meta($post->ID, '_lead_email', true),
|
||||||
|
'Phone' => get_post_meta($post->ID, '_lead_phone', true),
|
||||||
|
'Company / role' => get_post_meta($post->ID, '_lead_company', true),
|
||||||
|
'Focus area' => get_post_meta($post->ID, '_lead_focus', true),
|
||||||
|
'Message' => get_post_meta($post->ID, '_lead_message', true),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
echo '<div class="coaching-admin-meta">';
|
||||||
|
foreach ($fields as $label => $value) {
|
||||||
|
echo '<p><strong>' . esc_html($label) . ':</strong><br>' . nl2br(esc_html((string) $value)) . '</p>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_testimonial_meta_box_html($post) {
|
||||||
|
wp_nonce_field('coaching_testimonial_meta', 'coaching_testimonial_meta_nonce');
|
||||||
|
$role = get_post_meta($post->ID, '_testimonial_role', true);
|
||||||
|
echo '<p><label for="coaching-testimonial-role"><strong>Role / context</strong></label></p>';
|
||||||
|
echo '<input type="text" id="coaching-testimonial-role" name="coaching_testimonial_role" value="' . esc_attr((string) $role) . '" style="width:100%;" />';
|
||||||
|
echo '<p class="description">Example: Founder, Sample Client</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_save_testimonial_meta($post_id) {
|
||||||
|
if (!isset($_POST['coaching_testimonial_meta_nonce']) || !wp_verify_nonce(wp_unslash($_POST['coaching_testimonial_meta_nonce']), 'coaching_testimonial_meta')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isset($_POST['coaching_testimonial_role'])) {
|
||||||
|
update_post_meta($post_id, '_testimonial_role', sanitize_text_field(wp_unslash($_POST['coaching_testimonial_role'])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action('save_post_testimonial', 'coaching_mvp_save_testimonial_meta');
|
||||||
|
|
||||||
|
|
||||||
|
function coaching_mvp_current_request_origin() {
|
||||||
|
if (defined('WP_CLI') && WP_CLI) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = '';
|
||||||
|
if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
|
||||||
|
$parts = explode(',', (string) $_SERVER['HTTP_X_FORWARDED_HOST']);
|
||||||
|
$host = trim(end($parts));
|
||||||
|
} elseif (!empty($_SERVER['HTTP_HOST'])) {
|
||||||
|
$host = trim((string) $_SERVER['HTTP_HOST']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($host === '' || preg_match('/[^a-z0-9\-\.:\[\]]/i', $host)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scheme = 'http';
|
||||||
|
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||||
|
$parts = explode(',', (string) $_SERVER['HTTP_X_FORWARDED_PROTO']);
|
||||||
|
$candidate = strtolower(trim(end($parts)));
|
||||||
|
if (in_array($candidate, ['http', 'https'], true)) {
|
||||||
|
$scheme = $candidate;
|
||||||
|
}
|
||||||
|
} elseif (!empty($_SERVER['REQUEST_SCHEME']) && in_array($_SERVER['REQUEST_SCHEME'], ['http', 'https'], true)) {
|
||||||
|
$scheme = $_SERVER['REQUEST_SCHEME'];
|
||||||
|
} elseif (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
|
||||||
|
$scheme = 'https';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $scheme . '://' . $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_should_replace_local_host($url) {
|
||||||
|
$host = wp_parse_url($url, PHP_URL_HOST);
|
||||||
|
return in_array($host, ['localhost', '127.0.0.1', '::1'], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_replace_local_origin($url) {
|
||||||
|
$origin = coaching_mvp_current_request_origin();
|
||||||
|
if (!$origin || !coaching_mvp_should_replace_local_host($url)) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = (string) wp_parse_url($url, PHP_URL_PATH);
|
||||||
|
$query = wp_parse_url($url, PHP_URL_QUERY);
|
||||||
|
$fragment = wp_parse_url($url, PHP_URL_FRAGMENT);
|
||||||
|
|
||||||
|
$rebuilt = rtrim($origin, '/') . $path;
|
||||||
|
if ($query) {
|
||||||
|
$rebuilt .= '?' . $query;
|
||||||
|
}
|
||||||
|
if ($fragment) {
|
||||||
|
$rebuilt .= '#' . $fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rebuilt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_filter_option_home($value) {
|
||||||
|
return coaching_mvp_replace_local_origin((string) $value);
|
||||||
|
}
|
||||||
|
add_filter('option_home', 'coaching_mvp_filter_option_home');
|
||||||
|
add_filter('option_siteurl', 'coaching_mvp_filter_option_home');
|
||||||
|
|
||||||
|
function coaching_mvp_filter_generated_url($url) {
|
||||||
|
return coaching_mvp_replace_local_origin((string) $url);
|
||||||
|
}
|
||||||
|
add_filter('home_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('site_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('content_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('plugins_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('includes_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('rest_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('network_home_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
add_filter('network_site_url', 'coaching_mvp_filter_generated_url', 10, 1);
|
||||||
|
|
||||||
|
|
||||||
|
function coaching_mvp_replace_local_origin_in_html($html) {
|
||||||
|
$origin = coaching_mvp_current_request_origin();
|
||||||
|
if (!$origin || !is_string($html) || $html == '') {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace(
|
||||||
|
['http://localhost', 'https://localhost', 'http://127.0.0.1', 'https://127.0.0.1'],
|
||||||
|
$origin,
|
||||||
|
$html
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function coaching_mvp_filter_rendered_block_html($block_content) {
|
||||||
|
if (is_admin()) {
|
||||||
|
return $block_content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return coaching_mvp_replace_local_origin_in_html($block_content);
|
||||||
|
}
|
||||||
|
add_filter('render_block', 'coaching_mvp_filter_rendered_block_html', 10, 1);
|
||||||
Loading…
x
Reference in New Issue
Block a user