Tribe__Tickets_Plus__Commerce__WooCommerce__Main::save_ticket( int $post_id, Tribe__Tickets__Ticket_Object $ticket, array $raw_data = array() )

Saves a ticket (WooCommerce product).


Parameters

$post_id

(int) (Required) Post ID.

$ticket

(Tribe__Tickets__Ticket_Object) (Required) Ticket object.

$raw_data

(array) (Optional) Ticket data.

Default value: array()


Top ↑

Return

(int|bool)


Top ↑

Source

File: src/Tribe/Commerce/WooCommerce/Main.php

	public function save_ticket( $post_id, $ticket, $raw_data = array() ) {
		// assume we are updating until we find out otherwise
		$save_type = 'update';

		if ( empty( $ticket->ID ) ) {
			$save_type = 'create';

			/* Create main product post */
			$args = array(
				'post_status'  => 'publish',
				'post_type'    => 'product',
				'post_author'  => get_current_user_id(),
				'post_excerpt' => $ticket->description,
				'post_title'   => $ticket->name,
				'menu_order'   => tribe_get_request_var( 'menu_order', -1 ),
			);

			$ticket->ID = wp_insert_post( $args );
			$product    = wc_get_product( $ticket->ID );

			if ( ! $product ) {
				return false;
			}

			$product->set_sale_price( '' );
			$product->set_total_sales( 0 );
			$product->set_tax_status( 'taxable' );
			$product->set_tax_class( '' );
			$product->set_virtual( true );
			$product->set_catalog_visibility( 'hidden' );
			$product->set_downloadable( false );
			$product->set_purchase_note( '' );
			$product->set_weight( '' );
			$product->set_length( '' );
			$product->set_height( '' );
			$product->set_width( '' );
			$product->set_attributes( array() );
			$product->set_props( array(
				'date_on_sale_from' => '',
				'date_on_sale_to'   => '',
			) );
			$product->save();

			// Relate event <---> ticket
			add_post_meta( $ticket->ID, $this->event_key, $post_id );
		} else {
			$args = array(
				'ID'           => $ticket->ID,
				'post_excerpt' => $ticket->description,
				'post_title'   => $ticket->name,
				'menu_order'   => $ticket->menu_order,
			);

			$ticket->ID = wp_update_post( $args );
		}

		if ( ! $ticket->ID ) {
			return false;
		}

		/**
		 * Toggle filter to allow skipping the automatic SKU generation.
		 *
		 * @param bool $should_default_ticket_sku
		 */
		$should_default_ticket_sku = apply_filters( 'event_tickets_woo_should_default_ticket_sku', true );
		if ( $should_default_ticket_sku ) {
			// make sure the SKU is set to the correct value
			if ( ! empty( $raw_data['ticket_sku'] ) ) {
				$sku = $raw_data['ticket_sku'];
			} else {
				$post_author = get_post_field( 'post_author', $ticket->ID );
				$str         = $raw_data['ticket_name'];
				$str         = mb_strtoupper( $str, mb_detect_encoding( $str ) );
				$sku         = "{$ticket->ID}-{$post_author}-" . str_replace( ' ', '-', $str );
			}

			update_post_meta( $ticket->ID, '_sku', $sku );
		}


		// Updates if we should show Description
		$ticket->show_description = isset( $ticket->show_description ) && tribe_is_truthy( $ticket->show_description ) ? 'yes' : 'no';
		update_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_show_description, $ticket->show_description );

		/**
		 * Allow for the prevention of updating ticket price on update.
		 *
		 * @param boolean
		 * @param WP_Post
		 */
		$can_update_ticket_price = apply_filters( 'tribe_tickets_can_update_ticket_price', true, $ticket );

		if ( $can_update_ticket_price ) {
			update_post_meta( $ticket->ID, '_regular_price', $ticket->price );

			// Do not update _price if the ticket is on sale: the user should edit this in the WC product editor
			if ( ! wc_get_product( $ticket->ID )->is_on_sale() || 'create' === $save_type ) {
				update_post_meta( $ticket->ID, '_price', $ticket->price );
			}
		}

		// Fetches all Ticket Form Datas
		$data = Tribe__Utils__Array::get( $raw_data, 'tribe-ticket', array() );

		// Before merging with defaults check the stock data provided
		$stock_provided = ! empty( $data['stock'] ) && '' !== trim( $data['stock'] );

		// By default it is an Unlimited Stock without Global stock
		$defaults = array(
			'mode' => 'own',
		);

		$data = wp_parse_args( $data, $defaults );

		// Sanitize Mode
		$data['mode'] = filter_var( $data['mode'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );

		// Fetch the Global stock Instance for this Event
		$event_stock = new Tribe__Tickets__Global_Stock( $post_id );

		// Only need to do this if we haven't already set one - they shouldn't be able to edit it from here otherwise
		if ( ! $event_stock->is_enabled() ) {
			if ( isset( $data['event_capacity'] ) ) {
				$data['event_capacity'] = trim( filter_var( $data['event_capacity'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH ) );

				// If empty we need to modify to -1
				if ( '' === $data['event_capacity'] ) {
					$data['event_capacity'] = -1;
				}

				// Makes sure it's an Int after this point
				$data['event_capacity'] = (int) $data['event_capacity'];

				// We need to update event post meta - if we've set a global stock
				$event_stock->enable();
				$event_stock->set_stock_level( $data['event_capacity'] );

				// Update Event capacity
				update_post_meta( $post_id, tribe( 'tickets.handler' )->key_capacity, $data['event_capacity'] );
			}
		} else {
			// If the Global Stock is configured we pull it from the Event
			$data['event_capacity'] = tribe_tickets_get_capacity( $post_id );
		}

		// Default Capacity will be 0
		$default_capacity   = 0;
		$is_capacity_passed = true;

		// If we have Event Global stock we fetch that Stock
		if ( $event_stock->is_enabled() ) {
			$default_capacity = $data['event_capacity'];
		}

		// Fetch capacity field, if we don't have it use default (defined above)
		$data['capacity'] = trim( Tribe__Utils__Array::get( $data, 'capacity', $default_capacity ) );

		// If empty we need to modify to the default
		if ( '' !== $data['capacity'] ) {
			// Makes sure it's an Int after this point
			$data['capacity'] = (int) $data['capacity'];

			// The only available value lower than zero is -1 which is unlimited
			if ( 0 > $data['capacity'] ) {
				$data['capacity'] = -1;
			}

			$default_capacity = $data['capacity'];
		}

		// Fetch the stock if defined, otherwise use Capacity field
		$data['stock'] = trim( Tribe__Utils__Array::get( $data, 'stock', $default_capacity ) );

		// If empty we need to modify to what every capacity was
		if ( '' === $data['stock'] ) {
			$data['stock'] = $default_capacity;
		}

		// Makes sure it's an Int after this point
		$data['stock'] = (int) $data['stock'];

		if ( '' !== $data['mode'] ) {
			if ( 'update' === $save_type ) {
				$totals        = tribe( 'tickets.handler' )->get_ticket_totals( $ticket->ID );
				$data['stock'] -= $totals['pending'] + $totals['sold'];
			}

			// In here is safe to check because we don't have unlimted = -1
			$status = ( 0 < $data['stock'] ) ? 'instock' : 'outofstock';

			update_post_meta( $ticket->ID, Tribe__Tickets__Global_Stock::TICKET_STOCK_MODE, $data['mode'] );
			update_post_meta( $ticket->ID, '_stock', $data['stock'] );
			update_post_meta( $ticket->ID, '_stock_status', $status );
			update_post_meta( $ticket->ID, '_backorders', 'no' );
			update_post_meta( $ticket->ID, '_manage_stock', 'yes' );

			// Prevent Ticket Capacity from going higher then Event Capacity
			if (
				$event_stock->is_enabled()
				&& Tribe__Tickets__Global_Stock::OWN_STOCK_MODE !== $data['mode']
				&& '' !== $data['capacity']
				&& $data['capacity'] > $data['event_capacity']
			) {
				$data['capacity'] = $data['event_capacity'];
			}
		} else {
			// Unlimited Tickets
			// Besides setting _manage_stock to "no" we should remove the associated stock fields if set previously
			update_post_meta( $ticket->ID, '_manage_stock', 'no' );
			delete_post_meta( $ticket->ID, '_stock_status' );
			delete_post_meta( $ticket->ID, '_stock' );
			delete_post_meta( $ticket->ID, Tribe__Tickets__Global_Stock::TICKET_STOCK_CAP );
			delete_post_meta( $ticket->ID, Tribe__Tickets__Global_Stock::TICKET_STOCK_MODE );

			// Set Capacity -1 when we don't have a stock mode, which means unlimited
			$data['capacity'] = -1;
		}

		if ( '' !== $data['capacity'] ) {
			// Update Ticket capacity
			update_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_capacity, $data['capacity'] );
		}

		// Delete total Stock cache
		delete_transient( 'wc_product_total_stock_' . $ticket->ID );

		if ( ! empty( $raw_data['ticket_start_date'] ) ) {
			$start_date = Tribe__Date_Utils::maybe_format_from_datepicker( $raw_data['ticket_start_date'] );

			if ( isset( $raw_data['ticket_start_time'] ) ) {
				$start_date .= ' ' . $raw_data['ticket_start_time'];
			}

			$ticket->start_date  = date( Tribe__Date_Utils::DBDATETIMEFORMAT, strtotime( $start_date ) );
			$previous_start_date = get_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_start_date, true );

			// Only update when we are modifying
			if ( $ticket->start_date !== $previous_start_date ) {
				update_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_start_date, $ticket->start_date );
			}
		} else {
			delete_post_meta( $ticket->ID, '_ticket_start_date' );
		}

		if ( ! empty( $raw_data['ticket_start_date'] ) ) {
			$end_date = Tribe__Date_Utils::maybe_format_from_datepicker( $raw_data['ticket_end_date'] );

			if ( isset( $raw_data['ticket_end_time'] ) ) {
				$end_date .= ' ' . $raw_data['ticket_end_time'];
			}

			$ticket->end_date  = date( Tribe__Date_Utils::DBDATETIMEFORMAT, strtotime( $end_date ) );
			$previous_end_date = get_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_end_date, true );

			// Only update when we are modifying
			if ( $ticket->end_date !== $previous_end_date ) {
				update_post_meta( $ticket->ID, tribe( 'tickets.handler' )->key_end_date, $ticket->end_date );
			}
		} else {
			delete_post_meta( $ticket->ID, '_ticket_end_date' );
		}

		tribe( 'tickets.version' )->update( $ticket->ID );

		/**
		 * Generic action fired after saving a ticket (by type)
		 *
		 * @param int                           Post ID of post the ticket is tied to
		 * @param Tribe__Tickets__Ticket_Object Ticket that was just saved
		 * @param array                         Ticket data
		 * @param string                        Commerce engine class
		 */
		do_action( 'event_tickets_after_' . $save_type . '_ticket', $post_id, $ticket, $raw_data, __CLASS__ );

		/**
		 * Generic action fired after saving a ticket
		 *
		 * @param int                           Post ID of post the ticket is tied to
		 * @param Tribe__Tickets__Ticket_Object Ticket that was just saved
		 * @param array                         Ticket data
		 * @param string                        Commerce engine class
		 */
		do_action( 'event_tickets_after_save_ticket', $post_id, $ticket, $raw_data, __CLASS__ );

		return $ticket->ID;
	}