upskill-event-manager/includes/database/class-hvac-contact-submissions-table.php
bengizmo 37f4180e1c feat: Add massive missing plugin infrastructure to repository
🚨 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>
2025-08-11 13:30:11 -03:00

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
)
);
}
}