🚨 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>
343 lines
No EOL
11 KiB
PHP
343 lines
No EOL
11 KiB
PHP
<?php
|
|
/**
|
|
* Handles data retrieval for the Order Summary page.
|
|
* Follows the pattern of HVAC_Event_Summary_Data.
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
class HVAC_Order_Summary_Data {
|
|
|
|
/**
|
|
* The ID of the order.
|
|
*
|
|
* @var int|null
|
|
*/
|
|
private $order_id = null;
|
|
|
|
/**
|
|
* The order object (could be WooCommerce, RSVP, etc.).
|
|
*
|
|
* @var object|null
|
|
*/
|
|
private $order_object = null;
|
|
|
|
/**
|
|
* Array of event IDs associated with this order
|
|
*
|
|
* @var array
|
|
*/
|
|
private $event_ids = [];
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param int $order_id The ID of the order to retrieve data for.
|
|
*/
|
|
public function __construct( $order_id ) {
|
|
$this->order_id = absint( $order_id );
|
|
$this->order_object = $this->load_order_object( $this->order_id );
|
|
|
|
// Load associated events
|
|
if ($this->is_valid_order()) {
|
|
$this->event_ids = $this->get_associated_events();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load the order object based on the order ID.
|
|
*
|
|
* @param int $order_id
|
|
* @return object|null
|
|
*/
|
|
private function load_order_object( $order_id ) {
|
|
// WooCommerce order
|
|
if ( class_exists( 'WC_Order' ) && function_exists( 'wc_get_order' ) ) {
|
|
$order = wc_get_order( $order_id );
|
|
if ( $order ) {
|
|
return $order;
|
|
}
|
|
}
|
|
|
|
// Event Tickets RSVP/Tribe order (fallback)
|
|
if ( class_exists( 'Tribe__Tickets__RSVP' ) ) {
|
|
// Implementation depends on how RSVP orders are stored
|
|
// This is a placeholder for potential RSVP orders
|
|
}
|
|
|
|
// Add additional logic for other ticket providers if needed
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Check if the order is valid.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_valid_order() {
|
|
return ! is_null( $this->order_object );
|
|
}
|
|
|
|
/**
|
|
* Check if the current user has permission to view this order.
|
|
* Users can only view orders for events they created.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function user_can_view_order() {
|
|
// User must be logged in
|
|
if (!is_user_logged_in()) {
|
|
return false;
|
|
}
|
|
|
|
// Order must be valid
|
|
if (!$this->is_valid_order()) {
|
|
return false;
|
|
}
|
|
|
|
// Admin users can view all orders
|
|
if (current_user_can('manage_options')) {
|
|
return true;
|
|
}
|
|
|
|
// Get the current user ID
|
|
$current_user_id = get_current_user_id();
|
|
|
|
// Check if the user is the author of any of the events in this order
|
|
foreach ($this->event_ids as $event_id) {
|
|
$event = get_post($event_id);
|
|
if ($event && $event->post_author == $current_user_id) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get event IDs associated with this order.
|
|
*
|
|
* @return array Array of event IDs
|
|
*/
|
|
public function get_associated_events() {
|
|
$event_ids = [];
|
|
|
|
// Get attendees for this order
|
|
$attendees = [];
|
|
if (function_exists('tribe_tickets_get_order_attendees')) {
|
|
$attendees = tribe_tickets_get_order_attendees($this->order_id);
|
|
}
|
|
|
|
// Extract event IDs from attendees
|
|
foreach ($attendees as $attendee) {
|
|
if (isset($attendee['event_id'])) {
|
|
$event_ids[] = absint($attendee['event_id']);
|
|
}
|
|
}
|
|
|
|
return array_unique($event_ids);
|
|
}
|
|
|
|
/**
|
|
* Get basic order details.
|
|
*
|
|
* @return array|null
|
|
*/
|
|
public function get_order_details() {
|
|
if ( ! $this->is_valid_order() ) {
|
|
return null;
|
|
}
|
|
|
|
$details = [
|
|
'order_id' => $this->order_id,
|
|
'order_number' => null,
|
|
'purchaser_name'=> null,
|
|
'purchaser_email'=> null,
|
|
'purchase_date' => null,
|
|
'total_price' => null,
|
|
'status' => null,
|
|
'tickets' => [],
|
|
'events' => [],
|
|
'billing_address' => null,
|
|
'payment_method' => null,
|
|
'organization' => null,
|
|
];
|
|
|
|
// WooCommerce order details
|
|
if ( $this->order_object instanceof WC_Order ) {
|
|
$details['order_number'] = $this->order_object->get_order_number();
|
|
$details['purchaser_name'] = $this->order_object->get_billing_first_name() . ' ' . $this->order_object->get_billing_last_name();
|
|
$details['purchaser_email']= $this->order_object->get_billing_email();
|
|
$details['purchase_date'] = $this->order_object->get_date_created() ? $this->order_object->get_date_created()->date( 'Y-m-d H:i:s' ) : null;
|
|
$details['total_price'] = $this->order_object->get_formatted_order_total();
|
|
$details['status'] = $this->order_object->get_status();
|
|
$details['tickets'] = $this->get_order_tickets();
|
|
$details['events'] = $this->get_event_details();
|
|
|
|
// Get billing address
|
|
$address_parts = [
|
|
$this->order_object->get_billing_address_1(),
|
|
$this->order_object->get_billing_address_2(),
|
|
$this->order_object->get_billing_city(),
|
|
$this->order_object->get_billing_state(),
|
|
$this->order_object->get_billing_postcode(),
|
|
$this->order_object->get_billing_country()
|
|
];
|
|
|
|
// Filter out empty address parts and join
|
|
$address_parts = array_filter($address_parts);
|
|
$details['billing_address'] = implode(', ', $address_parts);
|
|
|
|
// Get payment method
|
|
$details['payment_method'] = $this->order_object->get_payment_method_title();
|
|
|
|
// Get organization (company name)
|
|
$details['organization'] = $this->order_object->get_billing_company();
|
|
}
|
|
|
|
// Add additional providers here if needed
|
|
|
|
return $details;
|
|
}
|
|
|
|
/**
|
|
* Get ticket/attendee information for the order.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_order_tickets() {
|
|
$tickets = [];
|
|
|
|
// WooCommerce + Event Tickets Plus
|
|
if ( $this->order_object instanceof WC_Order && function_exists( 'tribe_tickets_get_order_attendees' ) ) {
|
|
$order_id = $this->order_id;
|
|
$attendees = tribe_tickets_get_order_attendees( $order_id );
|
|
|
|
foreach ( $attendees as $attendee ) {
|
|
$event_id = $attendee['event_id'] ?? null;
|
|
$event_title = '';
|
|
|
|
if ($event_id) {
|
|
$event_title = get_the_title($event_id);
|
|
}
|
|
|
|
$tickets[] = [
|
|
'attendee_id' => $attendee['attendee_id'] ?? null,
|
|
'ticket_type' => $attendee['ticket_name'] ?? null,
|
|
'ticket_type_id' => $attendee['product_id'] ?? null,
|
|
'attendee_name' => $attendee['holder_name'] ?? null,
|
|
'attendee_email' => $attendee['holder_email'] ?? null,
|
|
'security_code' => $attendee['security_code'] ?? null,
|
|
'checked_in' => isset( $attendee['check_in'] ) ? (bool) $attendee['check_in'] : false,
|
|
'event_id' => $event_id,
|
|
'event_title' => $event_title,
|
|
'price' => $attendee['price'] ?? $attendee['price_paid'] ?? null,
|
|
'additional_fields' => $this->get_attendee_additional_fields($attendee),
|
|
];
|
|
}
|
|
}
|
|
|
|
// Add additional providers here if needed
|
|
|
|
return $tickets;
|
|
}
|
|
|
|
/**
|
|
* Get details of events associated with this order.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_event_details() {
|
|
$events = [];
|
|
|
|
foreach ($this->event_ids as $event_id) {
|
|
$event = get_post($event_id);
|
|
if (!$event) {
|
|
continue;
|
|
}
|
|
|
|
$event_data = [
|
|
'id' => $event_id,
|
|
'title' => $event->post_title,
|
|
'permalink' => get_permalink($event_id),
|
|
'start_date' => null,
|
|
'end_date' => null,
|
|
'venue' => null,
|
|
];
|
|
|
|
// Add Event Calendar specific data if available
|
|
if (function_exists('tribe_get_start_date')) {
|
|
$event_data['start_date'] = tribe_get_start_date($event_id, false);
|
|
$event_data['end_date'] = tribe_get_end_date($event_id, false);
|
|
|
|
if (function_exists('tribe_get_venue')) {
|
|
$event_data['venue'] = tribe_get_venue($event_id);
|
|
}
|
|
}
|
|
|
|
$events[] = $event_data;
|
|
}
|
|
|
|
return $events;
|
|
}
|
|
|
|
/**
|
|
* Get additional fields for an attendee.
|
|
* These could be custom fields collected during checkout.
|
|
*
|
|
* @param array $attendee The attendee data
|
|
* @return array
|
|
*/
|
|
private function get_attendee_additional_fields($attendee) {
|
|
$additional_fields = [];
|
|
|
|
// Check for meta data stored with the attendee
|
|
if (isset($attendee['attendee_meta']) && is_array($attendee['attendee_meta'])) {
|
|
foreach ($attendee['attendee_meta'] as $key => $value) {
|
|
// Skip internal or empty fields
|
|
if (strpos($key, '_') === 0 || empty($value)) {
|
|
continue;
|
|
}
|
|
|
|
// Format field name for display
|
|
$field_name = ucwords(str_replace(['_', '-'], ' ', $key));
|
|
|
|
$additional_fields[$key] = [
|
|
'label' => $field_name,
|
|
'value' => $value
|
|
];
|
|
}
|
|
}
|
|
|
|
return $additional_fields;
|
|
}
|
|
|
|
/**
|
|
* Get order notes.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_order_notes() {
|
|
$notes = [];
|
|
|
|
if ($this->order_object instanceof WC_Order && function_exists('wc_get_order_notes')) {
|
|
$raw_notes = wc_get_order_notes([
|
|
'order_id' => $this->order_id,
|
|
'type' => 'customer',
|
|
]);
|
|
|
|
foreach ($raw_notes as $note) {
|
|
$notes[] = [
|
|
'id' => $note->id,
|
|
'content' => $note->content,
|
|
'date' => $note->date_created->date('Y-m-d H:i:s'),
|
|
'author' => $note->added_by,
|
|
];
|
|
}
|
|
}
|
|
|
|
return $notes;
|
|
}
|
|
} |