getInputs(); $name = $inputs['ticket_name'] ?? 'untitled'; $event_id = $inputs['event_id'] ?? '?'; $price = $inputs['price'] ?? 0; $price_str = $price > 0 ? " at `{$price}`" : ' (free)'; return "Create ticket `{$name}`{$price_str} on event #{$event_id}"; } public function get_approval_inputs(): array { return $this->getInputs(); } public function __invoke( int $event_id, string $ticket_name, string $ticket_slug, int $available_tickets, ?float $price = null, ?int $min_ticket = null, ?int $max_ticket = null, ?string $start_date = null, ?string $end_date = null, ?string $start_time = null, ?string $end_time = null ): array { $check = $this->guard( 'etn_manage_event' ); if ( $check ) { return $check; } try { if ( $event_id <= 0 ) { return [ 'error' => 'event_id must be a positive integer.' ]; } $post = get_post( $event_id ); if ( ! $post || 'etn' !== $post->post_type ) { return [ 'error' => "No Eventin event found with ID {$event_id}." ]; } if ( empty( trim( $ticket_name ) ) ) { return [ 'error' => 'ticket_name is required.' ]; } if ( empty( trim( $ticket_slug ) ) ) { return [ 'error' => 'ticket_slug is required.' ]; } $sanitized_slug = sanitize_title( $ticket_slug ); if ( empty( $sanitized_slug ) ) { return [ 'error' => 'ticket_slug must contain valid URL-safe characters.' ]; } if ( $available_tickets < 0 ) { return [ 'error' => 'available_tickets must be a non-negative integer.' ]; } if ( null !== $start_date && '' !== trim( $start_date ) ) { $parsed = \DateTime::createFromFormat( 'Y-m-d', $start_date ); if ( ! $parsed || $parsed->format( 'Y-m-d' ) !== $start_date ) { return [ 'error' => 'start_date must be in YYYY-MM-DD format.' ]; } } if ( null !== $end_date && '' !== trim( $end_date ) ) { $parsed = \DateTime::createFromFormat( 'Y-m-d', $end_date ); if ( ! $parsed || $parsed->format( 'Y-m-d' ) !== $end_date ) { return [ 'error' => 'end_date must be in YYYY-MM-DD format.' ]; } } if ( null !== $start_date && null !== $end_date ) { $s = trim( $start_date ); $e = trim( $end_date ); if ( '' !== $s && '' !== $e && $e < $s ) { return [ 'error' => 'end_date must be on or after start_date.' ]; } } if ( null !== $start_time && '' !== trim( $start_time ) ) { $parsed = \DateTime::createFromFormat( 'H:i:s', $start_time ); if ( ! $parsed || $parsed->format( 'H:i:s' ) !== $start_time ) { $parsed12 = \DateTime::createFromFormat( 'h:i:s A', $start_time ); if ( ! $parsed12 ) { return [ 'error' => 'start_time must be in HH:MM:SS or HH:MM:SS AM/PM format.' ]; } } } if ( null !== $end_time && '' !== trim( $end_time ) ) { $parsed = \DateTime::createFromFormat( 'H:i:s', $end_time ); if ( ! $parsed || $parsed->format( 'H:i:s' ) !== $end_time ) { $parsed12 = \DateTime::createFromFormat( 'h:i:s A', $end_time ); if ( ! $parsed12 ) { return [ 'error' => 'end_time must be in HH:MM:SS or HH:MM:SS AM/PM format.' ]; } } } $existing_variations_raw = get_post_meta( $event_id, 'etn_ticket_variations', true ); $existing_variations = []; if ( ! empty( $existing_variations_raw ) ) { $decoded = is_string( $existing_variations_raw ) ? json_decode( $existing_variations_raw, true ) : $existing_variations_raw; $existing_variations = is_array( $decoded ) ? $decoded : []; } foreach ( $existing_variations as $existing ) { if ( isset( $existing['etn_ticket_slug'] ) && $existing['etn_ticket_slug'] === $sanitized_slug ) { return [ 'error' => "A ticket with slug `{$sanitized_slug}` already exists on event #{$event_id}. " . 'Use a different ticket_slug.', ]; } } $new_ticket = [ 'etn_ticket_name' => sanitize_text_field( $ticket_name ), 'etn_avaiilable_tickets' => absint( $available_tickets ), 'etn_ticket_price' => null !== $price ? (float) $price : 0.0, 'etn_ticket_slug' => $sanitized_slug, 'etn_min_ticket' => null !== $min_ticket ? absint( $min_ticket ) : 0, 'etn_max_ticket' => null !== $max_ticket ? absint( $max_ticket ) : 0, 'etn_enable_ticket' => true, 'etn_sold_tickets' => 0, 'start_date' => is_string( $start_date ) ? trim( $start_date ) : '', 'end_date' => is_string( $end_date ) ? trim( $end_date ) : '', 'start_time' => is_string( $start_time ) ? trim( $start_time ) : '', 'end_time' => is_string( $end_time ) ? trim( $end_time ) : '', ]; $updated_variations = $existing_variations; $updated_variations[] = $new_ticket; $body = [ 'title' => get_the_title( $event_id ), 'timezone' => get_post_meta( $event_id, 'event_timezone', true ) ?: 'UTC', 'start_date' => get_post_meta( $event_id, 'etn_start_date', true ) ?: gmdate( 'Y-m-d' ), 'end_date' => get_post_meta( $event_id, 'etn_end_date', true ) ?: gmdate( 'Y-m-d' ), 'start_time' => get_post_meta( $event_id, 'etn_start_time', true ) ?: '00:00:00', 'end_time' => get_post_meta( $event_id, 'etn_end_time', true ) ?: '00:00:00', 'ticket_variations' => $updated_variations, ]; $request = new \WP_REST_Request( 'POST' ); $request->set_header( 'content-type', 'application/json' ); $request->set_body( wp_json_encode( $body ) ); $request->set_url_params( [ 'id' => $event_id ] ); $controller = new \Eventin\Event\Api\EventController(); $response = $controller->update_item( $request ); if ( is_wp_error( $response ) ) { return [ 'error' => $response->get_error_message() ]; } return [ 'success' => true, 'event_id' => $event_id, 'ticket_slug' => $sanitized_slug, 'edit_url' => get_edit_post_link( $event_id, 'raw' ), 'message' => "Ticket `{$ticket_name}` (slug: `{$sanitized_slug}`) added to event #{$event_id}.", ]; } catch ( \Exception $e ) { Log::error( 'Eventin_Create_Ticket_Tool error', [ 'error' => $e->getMessage() ] ); return [ 'error' => 'Failed to create ticket: ' . $e->getMessage() ]; } } }