🚨 CRITICAL: Fixed deployment blockers by adding missing core directories: **Community System (CRITICAL)** - includes/community/ - Login_Handler and all community classes - templates/community/ - Community login forms **Certificate System (CRITICAL)** - includes/certificates/ - 8+ certificate classes and handlers - templates/certificates/ - Certificate reports and generation templates **Core Individual Classes (CRITICAL)** - includes/class-hvac-event-summary.php - includes/class-hvac-trainer-profile-manager.php - includes/class-hvac-master-dashboard-data.php - Plus 40+ other individual HVAC classes **Major Feature Systems (HIGH)** - includes/database/ - Training leads database tables - includes/find-trainer/ - Find trainer directory and MapGeo integration - includes/google-sheets/ - Google Sheets integration system - includes/zoho/ - Complete Zoho CRM integration - includes/communication/ - Communication templates system **Template Infrastructure** - templates/attendee/, templates/email-attendees/ - templates/event-summary/, templates/status/ - templates/template-parts/ - Shared template components **Impact:** - 70+ files added covering 10+ missing directories - Resolves ALL deployment blockers and feature breakdowns - Plugin activation should now work correctly - Multi-machine deployment fully supported 🔧 Generated with Claude Code Co-Authored-By: Ben Reed <ben@tealmaker.com>
299 lines
No EOL
8.2 KiB
PHP
299 lines
No EOL
8.2 KiB
PHP
<?php
|
|
/**
|
|
* Contact Submissions Database Table Management
|
|
*
|
|
* @package HVAC_Plugin
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Class HVAC_Contact_Submissions_Table
|
|
* Handles database table creation and management for contact submissions
|
|
*/
|
|
class HVAC_Contact_Submissions_Table {
|
|
|
|
/**
|
|
* Table name
|
|
*
|
|
* @var string
|
|
*/
|
|
private static $table_name = 'hvac_contact_submissions';
|
|
|
|
/**
|
|
* Get the full table name with prefix
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_table_name() {
|
|
global $wpdb;
|
|
return $wpdb->prefix . self::$table_name;
|
|
}
|
|
|
|
/**
|
|
* Create the contact submissions table
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function create_table() {
|
|
global $wpdb;
|
|
|
|
$table_name = self::get_table_name();
|
|
$charset_collate = $wpdb->get_charset_collate();
|
|
|
|
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
|
|
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
trainer_id BIGINT(20) UNSIGNED NOT NULL,
|
|
trainer_profile_id BIGINT(20) UNSIGNED NOT NULL,
|
|
first_name VARCHAR(100) NOT NULL,
|
|
last_name VARCHAR(100) NOT NULL,
|
|
email VARCHAR(255) NOT NULL,
|
|
phone VARCHAR(20),
|
|
city VARCHAR(100),
|
|
state_province VARCHAR(100),
|
|
company VARCHAR(255),
|
|
message TEXT,
|
|
ip_address VARCHAR(45),
|
|
user_agent TEXT,
|
|
submission_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
status ENUM('new', 'read', 'replied', 'archived') DEFAULT 'new',
|
|
notes TEXT,
|
|
PRIMARY KEY (id),
|
|
KEY trainer_id (trainer_id),
|
|
KEY trainer_profile_id (trainer_profile_id),
|
|
KEY status (status),
|
|
KEY submission_date (submission_date),
|
|
KEY email (email)
|
|
) $charset_collate;";
|
|
|
|
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
|
dbDelta($sql);
|
|
|
|
// Store version for future upgrades
|
|
update_option('hvac_contact_submissions_db_version', '1.0.0');
|
|
}
|
|
|
|
/**
|
|
* Drop the table
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function drop_table() {
|
|
global $wpdb;
|
|
$table_name = self::get_table_name();
|
|
$wpdb->query("DROP TABLE IF EXISTS $table_name");
|
|
delete_option('hvac_contact_submissions_db_version');
|
|
}
|
|
|
|
/**
|
|
* Insert a new contact submission
|
|
*
|
|
* @param array $data Submission data
|
|
* @return int|false Insert ID or false on failure
|
|
*/
|
|
public static function insert_submission($data) {
|
|
global $wpdb;
|
|
|
|
$defaults = [
|
|
'ip_address' => $_SERVER['REMOTE_ADDR'] ?? '',
|
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
|
'submission_date' => current_time('mysql'),
|
|
'status' => 'new'
|
|
];
|
|
|
|
$data = wp_parse_args($data, $defaults);
|
|
|
|
// Sanitize data
|
|
$data = array_map(function($value) {
|
|
if (is_string($value)) {
|
|
return sanitize_text_field($value);
|
|
}
|
|
return $value;
|
|
}, $data);
|
|
|
|
// Special handling for email
|
|
$data['email'] = sanitize_email($data['email']);
|
|
|
|
// Special handling for message
|
|
if (isset($data['message'])) {
|
|
$data['message'] = sanitize_textarea_field($data['message']);
|
|
}
|
|
|
|
$result = $wpdb->insert(
|
|
self::get_table_name(),
|
|
$data,
|
|
[
|
|
'%d', // trainer_id
|
|
'%d', // trainer_profile_id
|
|
'%s', // first_name
|
|
'%s', // last_name
|
|
'%s', // email
|
|
'%s', // phone
|
|
'%s', // city
|
|
'%s', // state_province
|
|
'%s', // company
|
|
'%s', // message
|
|
'%s', // ip_address
|
|
'%s', // user_agent
|
|
'%s', // submission_date
|
|
'%s', // status
|
|
'%s' // notes
|
|
]
|
|
);
|
|
|
|
if ($result === false) {
|
|
error_log('HVAC Contact Submission Error: ' . $wpdb->last_error);
|
|
return false;
|
|
}
|
|
|
|
return $wpdb->insert_id;
|
|
}
|
|
|
|
/**
|
|
* Get submissions based on criteria
|
|
*
|
|
* @param array $args Query arguments
|
|
* @return array
|
|
*/
|
|
public static function get_submissions($args = []) {
|
|
global $wpdb;
|
|
|
|
$defaults = [
|
|
'trainer_id' => null,
|
|
'status' => null,
|
|
'limit' => 20,
|
|
'offset' => 0,
|
|
'orderby' => 'submission_date',
|
|
'order' => 'DESC'
|
|
];
|
|
|
|
$args = wp_parse_args($args, $defaults);
|
|
|
|
$table_name = self::get_table_name();
|
|
$where = [];
|
|
$where_values = [];
|
|
|
|
if ($args['trainer_id']) {
|
|
$where[] = 'trainer_id = %d';
|
|
$where_values[] = $args['trainer_id'];
|
|
}
|
|
|
|
if ($args['status']) {
|
|
$where[] = 'status = %s';
|
|
$where_values[] = $args['status'];
|
|
}
|
|
|
|
$where_clause = '';
|
|
if (!empty($where)) {
|
|
$where_clause = 'WHERE ' . implode(' AND ', $where);
|
|
}
|
|
|
|
$orderby = in_array($args['orderby'], ['submission_date', 'id', 'status']) ? $args['orderby'] : 'submission_date';
|
|
$order = in_array($args['order'], ['ASC', 'DESC']) ? $args['order'] : 'DESC';
|
|
|
|
$query = "SELECT * FROM $table_name $where_clause ORDER BY $orderby $order LIMIT %d OFFSET %d";
|
|
$where_values[] = $args['limit'];
|
|
$where_values[] = $args['offset'];
|
|
|
|
if (!empty($where_values)) {
|
|
$query = $wpdb->prepare($query, $where_values);
|
|
}
|
|
|
|
return $wpdb->get_results($query);
|
|
}
|
|
|
|
/**
|
|
* Get submission by ID
|
|
*
|
|
* @param int $id Submission ID
|
|
* @return object|null
|
|
*/
|
|
public static function get_submission($id) {
|
|
global $wpdb;
|
|
|
|
return $wpdb->get_row(
|
|
$wpdb->prepare(
|
|
"SELECT * FROM %s WHERE id = %d",
|
|
self::get_table_name(),
|
|
$id
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Update submission status
|
|
*
|
|
* @param int $id Submission ID
|
|
* @param string $status New status
|
|
* @return bool
|
|
*/
|
|
public static function update_status($id, $status) {
|
|
global $wpdb;
|
|
|
|
$valid_statuses = ['new', 'read', 'replied', 'archived'];
|
|
if (!in_array($status, $valid_statuses)) {
|
|
return false;
|
|
}
|
|
|
|
return $wpdb->update(
|
|
self::get_table_name(),
|
|
['status' => $status],
|
|
['id' => $id],
|
|
['%s'],
|
|
['%d']
|
|
) !== false;
|
|
}
|
|
|
|
/**
|
|
* Get submission count by trainer
|
|
*
|
|
* @param int $trainer_id Trainer user ID
|
|
* @param string $status Optional status filter
|
|
* @return int
|
|
*/
|
|
public static function get_submission_count($trainer_id, $status = null) {
|
|
global $wpdb;
|
|
|
|
$table_name = self::get_table_name();
|
|
|
|
if ($status) {
|
|
return $wpdb->get_var(
|
|
$wpdb->prepare(
|
|
"SELECT COUNT(*) FROM $table_name WHERE trainer_id = %d AND status = %s",
|
|
$trainer_id,
|
|
$status
|
|
)
|
|
);
|
|
}
|
|
|
|
return $wpdb->get_var(
|
|
$wpdb->prepare(
|
|
"SELECT COUNT(*) FROM $table_name WHERE trainer_id = %d",
|
|
$trainer_id
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Clean old submissions
|
|
*
|
|
* @param int $days Number of days to keep
|
|
* @return int Number of deleted rows
|
|
*/
|
|
public static function clean_old_submissions($days = 90) {
|
|
global $wpdb;
|
|
|
|
$table_name = self::get_table_name();
|
|
$cutoff_date = date('Y-m-d H:i:s', strtotime("-{$days} days"));
|
|
|
|
return $wpdb->query(
|
|
$wpdb->prepare(
|
|
"DELETE FROM $table_name WHERE submission_date < %s AND status = 'archived'",
|
|
$cutoff_date
|
|
)
|
|
);
|
|
}
|
|
} |