/** * Generate and store all the attendees information for a new order. */ public function generate_tickets() { if (empty($_POST['tickets_process']) || empty($_POST['attendee']) || empty($_POST['product_id'])) { return; } $has_tickets = $post_id = false; /** * RSVP specific action fired just before a RSVP-driven attendee tickets for an order are generated * * @param $data post Parameters comes from RSVP Form */ do_action('tribe_tickets_rsvp_before_order_processing', $_POST); $order_id = md5(time() . rand()); $attendee_email = empty($_POST['attendee']['email']) ? null : sanitize_email($_POST['attendee']['email']); $attendee_email = is_email($attendee_email) ? $attendee_email : null; $attendee_full_name = empty($_POST['attendee']['full_name']) ? null : sanitize_text_field($_POST['attendee']['full_name']); $attendee_optout = empty($_POST['attendee']['optout']) ? false : (bool) $_POST['attendee']['optout']; if (empty($_POST['attendee']['order_status']) || !$this->tickets_view->is_valid_rsvp_option($_POST['attendee']['order_status'])) { $attendee_order_status = 'yes'; } else { $attendee_order_status = $_POST['attendee']['order_status']; } if (!$attendee_email || !$attendee_full_name) { $url = get_permalink($post_id); $url = add_query_arg('rsvp_error', 1, $url); wp_redirect(esc_url_raw($url)); tribe_exit(); } $rsvp_options = $this->tickets_view->get_rsvp_options(null, false); // Iterate over each product foreach ((array) $_POST['product_id'] as $product_id) { $order_attendee_id = 0; // Get the event this tickets is for $post_id = get_post_meta($product_id, $this->event_key, true); if (empty($post_id)) { continue; } $ticket_type = $this->get_ticket($post_id, $product_id); // if there were no RSVP tickets for the product added to the cart, continue if (empty($_POST["quantity_{$product_id}"])) { continue; } // get the RSVP status `decrease_stock_by` value $status_stock_size = $rsvp_options[$attendee_order_status]['decrease_stock_by']; $ticket_qty = intval($_POST["quantity_{$product_id}"]); // to avoid tickets from not being created on a status stock size of 0 // let's take the status stock size into account and create a number of tickets // at least equal to the number of tickets the user requested $ticket_qty = $status_stock_size < 1 ? $ticket_qty : $status_stock_size * $ticket_qty; $qty = max($ticket_qty, 0); // Throw an error if Qty is bigger then Remaining if ($ticket_type->managing_stock() && $qty > $ticket_type->remaining()) { $url = add_query_arg('rsvp_error', 2, get_permalink($post_id)); wp_redirect(esc_url_raw($url)); tribe_exit(); } $has_tickets = true; /** * RSVP specific action fired just before a RSVP-driven attendee ticket for an event is generated * * @param $post_id ID of event * @param $ticket_type Ticket Type object for the product * @param $data post Parameters comes from RSVP Form */ do_action('tribe_tickets_rsvp_before_attendee_ticket_creation', $post_id, $ticket_type, $_POST); // Iterate over all the amount of tickets purchased (for this product) for ($i = 0; $i < $qty; $i++) { $attendee = array('post_status' => 'publish', 'post_title' => $attendee_full_name . ' | ' . ($i + 1), 'post_type' => self::ATTENDEE_OBJECT, 'ping_status' => 'closed'); // Insert individual ticket purchased $attendee_id = wp_insert_post($attendee); if ($status_stock_size > 0) { $sales = (int) get_post_meta($product_id, 'total_sales', true); update_post_meta($product_id, 'total_sales', ++$sales); } update_post_meta($attendee_id, self::ATTENDEE_PRODUCT_KEY, $product_id); update_post_meta($attendee_id, self::ATTENDEE_EVENT_KEY, $post_id); update_post_meta($attendee_id, self::ATTENDEE_RSVP_KEY, $attendee_order_status); update_post_meta($attendee_id, $this->security_code, $this->generate_security_code($attendee_id)); update_post_meta($attendee_id, $this->order_key, $order_id); update_post_meta($attendee_id, self::ATTENDEE_OPTOUT_KEY, (bool) $attendee_optout); update_post_meta($attendee_id, $this->full_name, $attendee_full_name); update_post_meta($attendee_id, $this->email, $attendee_email); /** * RSVP specific action fired when a RSVP-driven attendee ticket for an event is generated * * @param $attendee_id ID of attendee ticket * @param $post_id ID of event * @param $order_id RSVP order ID * @param $product_id RSVP product ID */ do_action('event_tickets_rsvp_attendee_created', $attendee_id, $post_id, $order_id); /** * Action fired when an RSVP attendee ticket is created * * @param $attendee_id ID of the attendee post * @param $post_id Event post ID * @param $product_id RSVP ticket post ID * @param $order_attendee_id Attendee # for order */ do_action('event_tickets_rsvp_ticket_created', $attendee_id, $post_id, $product_id, $order_attendee_id); $this->record_attendee_user_id($attendee_id); $order_attendee_id++; } /** * Action fired when an RSVP has had attendee tickets generated for it * * @param $product_id RSVP ticket post ID * @param $order_id ID of the RSVP order * @param $qty Quantity ordered */ do_action('event_tickets_rsvp_tickets_generated_for_product', $product_id, $order_id, $qty); // After Adding the Values we Update the Transient Tribe__Post_Transient::instance()->delete($post_id, Tribe__Tickets__Tickets::ATTENDEES_CACHE); } /** * Fires when an RSVP attendee tickets have been generated. * * @param int $order_id ID of the RSVP order * @param int $post_id ID of the post the order was placed for * @param string $attendee_order_status 'yes' if the user indicated they will attend */ do_action('event_tickets_rsvp_tickets_generated', $order_id, $post_id, $attendee_order_status); $send_mail_stati = array('yes'); /** * Filters whether a confirmation email should be sent or not for RSVP tickets. * * This applies to attendance and non attendance emails. * * @param bool $send_mail Defaults to `true`. */ $send_mail = apply_filters('tribe_tickets_rsvp_send_mail', true); if ($send_mail) { /** * Filters the attendee order stati that should trigger an attendance confirmation. * * Any attendee order status not listed here will trigger a non attendance email. * * @param array $send_mail_stati An array of default stati triggering an attendance email. * @param int $order_id ID of the RSVP order * @param int $post_id ID of the post the order was placed for * @param string $attendee_order_status 'yes' if the user indicated they will attend */ $send_mail_stati = apply_filters('tribe_tickets_rsvp_send_mail_stati', $send_mail_stati, $order_id, $post_id, $attendee_order_status); // No point sending tickets if their current intention is not to attend if ($has_tickets && in_array($attendee_order_status, $send_mail_stati)) { $this->send_tickets_email($order_id); } elseif ($has_tickets) { $this->send_non_attendance_confirmation($order_id, $post_id); } } // Redirect to the same page to prevent double purchase on refresh if (!empty($post_id)) { $url = get_permalink($post_id); $url = add_query_arg('rsvp_sent', 1, $url); wp_redirect(esc_url_raw($url)); tribe_exit(); } }