Implements automatic creation of required plugin pages (Community Login, Trainer Registration, Trainer Dashboard) upon plugin activation. This addresses E2E test failures caused by missing pages in the test environment. - Adds activation hook in `hvac-community-events.php` to call `hvac_ce_create_required_pages`. - The callback function checks for existing pages by slug and creates them using `wp_insert_post` if missing. Includes debug logging. Also fixes issues identified during E2E test debugging: - Corrects fatal error in `includes/community/class-login-handler.php` by replacing undefined constant `HVAC_COMMUNITY_EVENTS_PATH` with `HVAC_CE_PLUGIN_DIR`. - Updates `tests/e2e/tests/login.spec.ts` to use the correct selector `#wp-submit` for the login form submit button instead of `button[type="submit"]`. Documentation updates: - Adds `docs/automatic-page-creation-plan.md`. - Updates `README.md` regarding automatic page creation. - Updates Memory Bank files (`decisionLog.md`, `progress.md`, `activeContext.md`). Note: Activation hook logging did not appear during WP-CLI activation, requiring further investigation if page creation issues persist. E2E test confirmation pending.
409 lines
No EOL
16 KiB
PHP
409 lines
No EOL
16 KiB
PHP
<?php
|
|
/**
|
|
* Handles the HVAC trainer registration functionality
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class HVAC_Registration {
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct() {
|
|
// Register shortcode for registration form
|
|
add_shortcode('hvac_trainer_registration', array($this, 'registration_form'));
|
|
|
|
// Handle form submission
|
|
add_action('init', array($this, 'process_registration'));
|
|
|
|
// Enqueue styles
|
|
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
|
|
}
|
|
|
|
/**
|
|
* Registration form shortcode
|
|
*/
|
|
public function registration_form() {
|
|
ob_start();
|
|
|
|
// Display validation errors if they exist
|
|
if ($errors = get_transient('hvac_registration_errors')) {
|
|
echo '<div class="hvac-errors">';
|
|
foreach ($errors as $error) {
|
|
echo '<p class="error">'.$error.'</p>';
|
|
}
|
|
echo '</div>';
|
|
delete_transient('hvac_registration_errors');
|
|
}
|
|
|
|
// Form HTML will be generated here
|
|
?>
|
|
<div class="hvac-registration-form">
|
|
<h2>HVAC Trainer Registration</h2>
|
|
<form method="post" action="">
|
|
<?php wp_nonce_field('hvac_trainer_registration', 'hvac_registration_nonce'); ?>
|
|
|
|
<!-- Personal Information Section -->
|
|
<div class="form-section">
|
|
<h3>Personal Information</h3>
|
|
<div class="form-row">
|
|
<label for="first_name">First Name *</label>
|
|
<input type="text" name="first_name" id="first_name" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="last_name">Last Name *</label>
|
|
<input type="text" name="last_name" id="last_name" required>
|
|
</div>
|
|
|
|
<!-- Additional fields will be added here -->
|
|
</div>
|
|
|
|
<!-- Business Information Section -->
|
|
<div class="form-section">
|
|
<h3>Business Information</h3>
|
|
<div class="form-row">
|
|
<label for="business_name">Business Name *</label>
|
|
<input type="text" name="business_name" id="business_name" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="business_phone">Business Phone *</label>
|
|
<input type="tel" name="business_phone" id="business_phone" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="business_email">Business Email *</label>
|
|
<input type="email" name="business_email" id="business_email" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="business_website">Business Website (optional)</label>
|
|
<input type="url" name="business_website" id="business_website">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Address Information Section -->
|
|
<div class="form-section">
|
|
<h3>Address Information</h3>
|
|
<div class="form-row">
|
|
<label for="user_country">Country *</label>
|
|
<select name="user_country" id="user_country" required>
|
|
<option value="">Select Country</option>
|
|
<option value="United States">United States</option>
|
|
<option value="Canada">Canada</option>
|
|
<option value="">---</option>
|
|
<?php
|
|
// Additional countries would be loaded here
|
|
?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="user_state">State/Province *</label>
|
|
<select name="user_state" id="user_state" required>
|
|
<option value="Other">Other</option>
|
|
<!-- US states and Canadian provinces would be loaded here -->
|
|
</select>
|
|
<input type="text" name="user_state_other" id="user_state_other"
|
|
style="display:none; margin-top: 0.5rem;"
|
|
placeholder="Enter your state/province">
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="user_city">City *</label>
|
|
<input type="text" name="user_city" id="user_city" required>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label for="user_zip">Zip/Postal Code *</label>
|
|
<input type="text" name="user_zip" id="user_zip" required>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Training Information Section -->
|
|
<div class="form-section">
|
|
<h3>Training Information</h3>
|
|
|
|
<div class="form-row">
|
|
<label>Business Type *</label>
|
|
<div class="checkbox-group">
|
|
<label><input type="radio" name="business_type" value="Manufacturer" required> Manufacturer</label>
|
|
<label><input type="radio" name="business_type" value="Distributor"> Distributor</label>
|
|
<label><input type="radio" name="business_type" value="Contractor"> Contractor</label>
|
|
<label><input type="radio" name="business_type" value="Consultant"> Consultant</label>
|
|
<label><input type="radio" name="business_type" value="Educator"> Educator</label>
|
|
<label><input type="radio" name="business_type" value="Government"> Government</label>
|
|
<label><input type="radio" name="business_type" value="Other"> Other</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<label>Training Audience *</label>
|
|
<div class="checkbox-group">
|
|
<label><input type="checkbox" name="training_audience[]" value="Anyone"> Anyone (open to the public)</label>
|
|
<label><input type="checkbox" name="training_audience[]" value="Industry professionals"> Industry professionals</label>
|
|
<label><input type="checkbox" name="training_audience[]" value="Internal staff"> Internal staff in my company</label>
|
|
<label><input type="checkbox" name="training_audience[]" value="Registered students"> Registered students/members</label>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional training fields would go here -->
|
|
</div>
|
|
|
|
<div class="form-submit">
|
|
<input type="submit" name="hvac_register" value="Register">
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<?php
|
|
return ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Enqueue styles for the registration form
|
|
*/
|
|
public function enqueue_styles() {
|
|
wp_enqueue_style(
|
|
'hvac-registration-style',
|
|
HVAC_CE_PLUGIN_URL . 'assets/css/hvac-registration.css',
|
|
array(),
|
|
HVAC_CE_VERSION
|
|
);
|
|
|
|
wp_enqueue_script(
|
|
'hvac-registration-js',
|
|
HVAC_CE_PLUGIN_URL . 'assets/js/hvac-registration.js',
|
|
array('jquery'),
|
|
HVAC_CE_VERSION,
|
|
true
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Process registration form submission
|
|
*/
|
|
public function process_registration() {
|
|
if (!isset($_POST['hvac_registration_nonce']) ||
|
|
!wp_verify_nonce($_POST['hvac_registration_nonce'], 'hvac_trainer_registration')) {
|
|
return;
|
|
}
|
|
|
|
// Validate and process form data
|
|
if (isset($_POST['hvac_register'])) {
|
|
$errors = $this->validate_registration($_POST);
|
|
|
|
if (empty($errors)) {
|
|
// Process valid form submission
|
|
$user_id = $this->create_trainer_account($_POST);
|
|
|
|
if ($user_id && !is_wp_error($user_id)) {
|
|
$this->send_registration_notification($user_id, $_POST);
|
|
wp_safe_redirect(home_url('/registration-success/'));
|
|
exit;
|
|
}
|
|
} else {
|
|
// Store errors to display to user
|
|
set_transient('hvac_registration_errors', $errors, 60);
|
|
wp_safe_redirect(wp_get_referer());
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate registration form data
|
|
*/
|
|
/**
|
|
* Create HVAC trainer account
|
|
*/
|
|
private function create_trainer_account($data) {
|
|
// Generate username from email
|
|
$username = sanitize_user(current(explode('@', $data['business_email'])), true);
|
|
$counter = 1;
|
|
$original_username = $username;
|
|
|
|
// Ensure username is unique
|
|
while (username_exists($username)) {
|
|
$username = $original_username . $counter++;
|
|
}
|
|
|
|
// Create user
|
|
$user_id = wp_create_user(
|
|
$username,
|
|
$data['user_pass'],
|
|
$data['business_email']
|
|
);
|
|
|
|
if (is_wp_error($user_id)) {
|
|
return false;
|
|
}
|
|
|
|
// Set basic user info
|
|
wp_update_user([
|
|
'ID' => $user_id,
|
|
'first_name' => sanitize_text_field($data['first_name']),
|
|
'last_name' => sanitize_text_field($data['last_name']),
|
|
'display_name' => sanitize_text_field($data['first_name'] . ' ' . $data['last_name']),
|
|
'role' => 'hvac_trainer'
|
|
]);
|
|
|
|
// Save custom fields
|
|
update_user_meta($user_id, 'business_name', sanitize_text_field($data['business_name']));
|
|
update_user_meta($user_id, 'business_phone', sanitize_text_field($data['business_phone']));
|
|
update_user_meta($user_id, 'business_website', esc_url_raw($data['business_website']));
|
|
update_user_meta($user_id, 'user_country', sanitize_text_field($data['user_country']));
|
|
update_user_meta($user_id, 'user_state', sanitize_text_field($data['user_state']));
|
|
update_user_meta($user_id, 'user_city', sanitize_text_field($data['user_city']));
|
|
update_user_meta($user_id, 'user_zip', sanitize_text_field($data['user_zip']));
|
|
update_user_meta($user_id, 'business_type', sanitize_text_field($data['business_type']));
|
|
update_user_meta($user_id, 'training_audience', array_map('sanitize_text_field', $data['training_audience']));
|
|
|
|
// Create Events Calendar organizer profile
|
|
$this->create_organizer_profile($user_id, $data);
|
|
|
|
// Create venue if requested
|
|
if (isset($data['create_venue']) && $data['create_venue'] === 'Yes') {
|
|
$this->create_training_venue($user_id, $data);
|
|
}
|
|
|
|
// TODO: Send admin notification email
|
|
// TODO: Send welcome email to user
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Create a training venue in The Events Calendar
|
|
*/
|
|
/**
|
|
* Create organizer profile in The Events Calendar
|
|
*/
|
|
private function create_organizer_profile($user_id, $data) {
|
|
if (!function_exists('tribe_create_organizer')) {
|
|
return false;
|
|
}
|
|
|
|
$organizer_data = array(
|
|
'Organizer' => sanitize_text_field($data['business_name']),
|
|
'Phone' => sanitize_text_field($data['business_phone']),
|
|
'Email' => sanitize_email($data['business_email']),
|
|
'Website' => esc_url_raw($data['business_website']),
|
|
);
|
|
|
|
$organizer_id = tribe_create_organizer($organizer_data);
|
|
|
|
if ($organizer_id) {
|
|
// Associate organizer with user
|
|
update_user_meta($user_id, '_hvac_organizer_id', $organizer_id);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private function create_training_venue($user_id, $data) {
|
|
if (!function_exists('tribe_create_venue')) {
|
|
return false;
|
|
}
|
|
|
|
$venue_data = array(
|
|
'Venue' => sanitize_text_field($data['business_name']),
|
|
'Address' => sanitize_text_field($data['user_city']),
|
|
'City' => sanitize_text_field($data['user_city']),
|
|
'State' => sanitize_text_field($data['user_state']),
|
|
'Zip' => sanitize_text_field($data['user_zip']),
|
|
'Country' => sanitize_text_field($data['user_country']),
|
|
'ShowMap' => true,
|
|
'ShowMapLink' => true
|
|
);
|
|
|
|
$venue_id = tribe_create_venue($venue_data);
|
|
|
|
if ($venue_id) {
|
|
// Associate venue with user
|
|
update_user_meta($user_id, '_hvac_training_venue_id', $venue_id);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Send admin notification about new trainer registration
|
|
*/
|
|
private function send_registration_notification($user_id, $data) {
|
|
$options = get_option('hvac_ce_options');
|
|
$emails = isset($options['notification_emails']) ?
|
|
array_map('trim', explode(',', $options['notification_emails'])) :
|
|
array(get_option('admin_email'));
|
|
|
|
if (empty($emails)) {
|
|
return false;
|
|
}
|
|
|
|
$user = get_userdata($user_id);
|
|
$subject = sprintf(__('New HVAC Trainer Registration: %s', 'hvac-ce'), $user->display_name);
|
|
|
|
$message = __('A new HVAC trainer has registered:', 'hvac-ce') . "\n\n";
|
|
$message .= __('Name:', 'hvac-ce') . ' ' . $user->first_name . ' ' . $user->last_name . "\n";
|
|
$message .= __('Email:', 'hvac-ce') . ' ' . $user->user_email . "\n";
|
|
$message .= __('Business:', 'hvac-ce') . ' ' . get_user_meta($user_id, 'business_name', true) . "\n";
|
|
$message .= __('Phone:', 'hvac-ce') . ' ' . get_user_meta($user_id, 'business_phone', true) . "\n";
|
|
$message .= __('Location:', 'hvac-ce') . ' ' .
|
|
get_user_meta($user_id, 'user_city', true) . ', ' .
|
|
get_user_meta($user_id, 'user_state', true) . "\n\n";
|
|
$message .= __('Business Type:', 'hvac-ce') . ' ' . get_user_meta($user_id, 'business_type', true) . "\n";
|
|
$message .= __('Training Audience:', 'hvac-ce') . ' ' .
|
|
implode(', ', get_user_meta($user_id, 'training_audience', true)) . "\n\n";
|
|
$message .= __('View profile:', 'hvac-ce') . ' ' .
|
|
admin_url('user-edit.php?user_id=' . $user_id);
|
|
|
|
foreach ($emails as $email) {
|
|
if (is_email($email)) {
|
|
wp_mail($email, $subject, $message);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function validate_registration($data) { // Changed visibility to public
|
|
$errors = array();
|
|
|
|
// Required field validation
|
|
$required = array(
|
|
'first_name', 'last_name', 'business_name',
|
|
'business_phone', 'business_email', 'user_country',
|
|
'user_state', 'user_city', 'user_zip', 'business_type'
|
|
);
|
|
|
|
foreach ($required as $field) {
|
|
if (empty($data[$field])) {
|
|
$errors[$field] = 'This field is required';
|
|
}
|
|
}
|
|
|
|
// Email validation
|
|
if (!is_email($data['business_email'])) {
|
|
$errors['business_email'] = 'Please enter a valid email address';
|
|
}
|
|
|
|
// Password validation
|
|
if (empty($data['user_pass']) || strlen($data['user_pass']) < 8 ||
|
|
!preg_match('/[A-Z]/', $data['user_pass']) ||
|
|
!preg_match('/[a-z]/', $data['user_pass']) ||
|
|
!preg_match('/[0-9]/', $data['user_pass'])) {
|
|
$errors['user_pass'] = 'Password must be at least 8 characters with uppercase, lowercase and numbers';
|
|
}
|
|
|
|
// URL validation
|
|
if (!empty($data['business_website']) && !filter_var($data['business_website'], FILTER_VALIDATE_URL)) {
|
|
$errors['business_website'] = 'Please enter a valid website URL';
|
|
}
|
|
|
|
return $errors;
|
|
}
|
|
}
|