Order_Repository
Class Order
Source
File: src/Tickets/Commerce/Repositories/Order_Repository.php
class Order_Repository extends Tribe__Repository {
/**
* The unique fragment that will be used to identify this repository filters.
*
* @since 5.1.9
*
* @var string
*/
protected $filter_name = 'tc_orders';
/**
* Key name to use when limiting lists of keys.
*
* @since 5.1.9
*
* @var string
*/
protected $key_name = \TEC\Tickets\Commerce::ABBR;
/**
* {@inheritdoc}
*/
public function __construct() {
parent::__construct();
$insert_status = tribe( Commerce\Status\Status_Handler::class )->get_insert_status();
// Set the order post type.
$this->default_args['post_type'] = Order::POSTTYPE;
$this->default_args['post_status'] = $insert_status->get_wp_slug();
$this->create_args['post_status'] = $insert_status->get_wp_slug();
$this->create_args['post_type'] = Order::POSTTYPE;
$this->create_args['currency'] = tribe_get_option( Commerce\Settings::$option_currency_code, 'USD' );
// Add event specific aliases.
$this->update_fields_aliases = array_merge(
$this->update_fields_aliases,
[
'gateway' => Order::$gateway_meta_key,
'gateway_order_id' => Order::$gateway_order_id_meta_key,
'items' => Order::$items_meta_key,
'total_value' => Order::$total_value_meta_key,
'currency' => Order::$currency_meta_key,
'purchaser_user_id' => Order::$purchaser_user_id_meta_key,
'purchaser_full_name' => Order::$purchaser_full_name_meta_key,
'purchaser_first_name' => Order::$purchaser_first_name_meta_key,
'purchaser_last_name' => Order::$purchaser_last_name_meta_key,
'purchaser_email' => Order::$purchaser_email_meta_key,
'hash' => Order::$hash_meta_key,
]
);
$this->schema = array_merge(
$this->schema,
[
'tickets' => [ $this, 'filter_by_tickets' ],
'tickets_not' => [ $this, 'filter_by_tickets_not' ],
'events' => [ $this, 'filter_by_events' ],
'events_not' => [ $this, 'filter_by_events_not' ],
]
);
$this->add_simple_meta_schema_entry( 'gateway', Order::$gateway_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'gateway_order_id', Order::$gateway_order_id_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'currency', Order::$currency_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'purchaser_full_name', Order::$purchaser_full_name_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'purchaser_first_name', Order::$purchaser_first_name_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'purchaser_last_name', Order::$purchaser_last_name_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'purchaser_email', Order::$purchaser_email_meta_key, 'meta_equals' );
$this->add_simple_meta_schema_entry( 'hash', Order::$hash_meta_key, 'meta_equals' );
}
/**
* {@inheritDoc}
*/
protected function format_item( $id ) {
$formatted = null === $this->formatter
? tec_tc_get_order( $id )
: $this->formatter->format_item( $id );
/**
* Filters a single formatted order result.
*
* @since 5.1.9
*
* @param mixed|\WP_Post $formatted The formatted event result, usually a post object.
* @param int $id The formatted post ID.
* @param \Tribe__Repository__Interface $this The current repository object.
*/
$formatted = apply_filters( 'tec_tickets_commerce_repository_order_format', $formatted, $id, $this );
return $formatted;
}
/**
* {@inheritdoc}
*/
public function filter_postarr_for_create( array $postarr ) {
if ( isset( $postarr['meta_input'] ) ) {
$postarr = $this->filter_meta_input( $postarr );
}
if ( ! empty( $postarr['gateway_payload'] ) ) {
$payload = $postarr['gateway_payload'];
unset( $postarr['gateway_payload'] );
$status = tribe( Commerce\Status\Status_Handler::class )->get_by_wp_slug( $this->create_args['post_status'] );
if ( $status ) {
$postarr['meta_input'][ Order::get_gateway_payload_meta_key( $status ) ] = $payload;
}
}
return parent::filter_postarr_for_create( $postarr );
}
/**
* {@inheritdoc}
*/
public function filter_postarr_for_update( array $postarr, $post_id ) {
if ( isset( $postarr['meta_input'] ) ) {
$postarr = $this->filter_meta_input( $postarr, $post_id );
}
if ( ! empty( $postarr['tickets_in_order'] ) ) {
$tickets = array_filter( array_unique( (array) $postarr['tickets_in_order'] ) );
unset( $postarr['tickets_in_order'] );
// Delete all of the previous ones when updating.
delete_post_meta( $post_id, Order::$tickets_in_order_meta_key );
foreach ( $tickets as $ticket_id ) {
add_post_meta( $post_id, Order::$tickets_in_order_meta_key, $ticket_id );
}
}
if ( ! empty( $postarr['events_in_order'] ) ) {
$events = array_filter( array_unique( (array) $postarr['events_in_order'] ) );
unset( $postarr['events_in_order'] );
// Delete all of the previous ones when updating.
delete_post_meta( $post_id, Order::$events_in_order_meta_key );
foreach ( $events as $event_id ) {
add_post_meta( $post_id, Order::$events_in_order_meta_key, $event_id );
}
}
if ( ! empty( $postarr['meta_input']['gateway_payload'] ) ) {
$payload = $postarr['meta_input']['gateway_payload'];
unset( $postarr['meta_input']['gateway_payload'] );
$status = tribe( Commerce\Status\Status_Handler::class )->get_by_wp_slug( $postarr['post_status'] );
if ( $status ) {
add_post_meta( $post_id, Order::get_gateway_payload_meta_key( $status ), $payload );
}
}
return parent::filter_postarr_for_update( $postarr, $post_id );
}
/**
* {@inheritDoc}
*/
protected function get_create_callback( array $postarr ) {
$callback = parent::get_create_callback( $postarr );
// only modify if the filters didn't change anything.
if ( 'wp_insert_post' === $callback ) {
$callback = [ $this, 'create_order_with_meta' ];
}
return $callback;
}
/**
* When creating an order via the repository there are two meta elements that need to be added using
* `add_post_meta` with the $unique param set to false.
*
* So we hijack the default create callback for this repository to allow for that behavior to exist.
*
* @since 5.1.9
*
* @param array $postarr The post array that will be used for the creation.
*
* @return int The Post ID.
*/
protected function create_order_with_meta( array $postarr ) {
$callback = parent::get_create_callback( $postarr );
$tickets = [];
if ( ! empty( $postarr['meta_input']['tickets_in_order'] ) ) {
$tickets = array_filter( array_unique( (array) $postarr['meta_input']['tickets_in_order'] ) );
unset( $postarr['meta_input']['tickets_in_order'] );
}
$events = [];
if ( ! empty( $postarr['meta_input']['events_in_order'] ) ) {
$events = array_filter( array_unique( (array) $postarr['meta_input']['events_in_order'] ) );
unset( $postarr['meta_input']['events_in_order'] );
}
$created = call_user_func( $callback, $postarr );
// Dont add in case we are dealing with a failed insertion.
if ( ! is_wp_error( $created ) ) {
foreach ( $events as $event_id ) {
add_post_meta( $created, Order::$events_in_order_meta_key, $event_id );
}
foreach ( $tickets as $ticket_id ) {
add_post_meta( $created, Order::$tickets_in_order_meta_key, $ticket_id );
}
}
return $created;
}
/**
* Filters the tickets data from the input so we can properly save the cart items.
*
* @since 5.1.9
*
* @param array $postarr Data set that needs filtering.
* @param null|int $post_id When we are dealing with an Update we have an ID here.
*
* @return array
*/
protected function filter_gateway_payload( $postarr, $post_id = null ) {
$meta = Arr::get( $postarr, 'meta_input', [] );
$items = Arr::get( $meta, 'gateway_payload', [] );
if ( ! empty( $items ) ) {
$statuses = tribe( Commerce\Status\Status_Handler::class )->get_all();
}
return $postarr;
}
/**
* Filters the tickets data from the input so we can properly save the cart items.
*
* @since 5.1.9
*
* @param array $postarr Data set that needs filtering.
* @param null|int $post_id When we are dealing with an Update we have an ID here.
*
* @return array
*/
protected function filter_items_input( $postarr, $post_id = null ) {
$meta = Arr::get( $postarr, 'meta_input', [] );
$items = Arr::get( $meta, Order::$items_meta_key, [] );
if ( ! empty( $items ) ) {
$ticket_ids = array_unique( array_filter( array_values( wp_list_pluck( $items, 'ticket_id' ) ) ) );
$event_objects = array_map( [ tribe( Module::class ), 'get_event_for_ticket' ], $ticket_ids );
$event_ids = array_unique( array_filter( array_values( wp_list_pluck( $event_objects, 'ID' ) ) ) );
// These will be remove right before actually creating the order.
$postarr['meta_input']['tickets_in_order'] = $ticket_ids;
$postarr['meta_input']['events_in_order'] = $event_ids;
}
return $postarr;
}
/**
* Filters the Purchaser data from the input so we can properly save the data.
*
* @since 5.1.9
*
* @param array $postarr Data set that needs filtering.
* @param null|int $post_id When we are dealing with an Update we have an ID here.
*
* @return array
*/
protected function filter_purchaser_input( $postarr, $post_id = null ) {
$meta = Arr::get( $postarr, 'meta_input', [] );
$purchaser = Arr::get( $meta, 'purchaser', [] );
if ( is_numeric( $purchaser ) && $user = get_userdata( $purchaser ) ) {
$full_name = $user->display_name;
$first_name = $user->first_name;
$last_name = $user->last_name;
$email = $user->user_email;
} else {
$full_name = Arr::get( $purchaser, 'full_name' );
$first_name = Arr::get( $purchaser, 'first_name' );
$last_name = Arr::get( $purchaser, 'last_name' );
$email = Arr::get( $purchaser, 'email' );
}
// Maybe set the first / last name.
if ( empty( $first_name ) || empty( $last_name ) ) {
$first_name = $full_name;
$last_name = '';
// Get first name and last name.
if ( false !== strpos( $full_name, ' ' ) ) {
$name_parts = explode( ' ', $full_name );
// First name is first text.
$first_name = array_shift( $name_parts );
// Last name is everything the first text.
$last_name = implode( ' ', $name_parts );
}
}
$postarr['meta_input'][ Order::$purchaser_email_meta_key ] = $email;
$postarr['meta_input'][ Order::$purchaser_full_name_meta_key ] = $full_name;
$postarr['meta_input'][ Order::$purchaser_first_name_meta_key ] = $first_name;
$postarr['meta_input'][ Order::$purchaser_last_name_meta_key ] = $last_name;
unset( $postarr['meta_input']['purchaser'] );
return $postarr;
}
/**
* Filters and updates the order meta to make sure it makes sense.
*
* @since 5.1.9
*
* @param array $postarr The update post array, passed entirely for context purposes.
* @param int $post_id The ID of the event that's being updated.
*
* @return array The filtered postarr array.
*/
protected function filter_meta_input( array $postarr, $post_id = null ) {
if ( ! empty( $postarr['meta_input']['purchaser'] ) ) {
$postarr = $this->filter_purchaser_input( $postarr, $post_id );
}
if ( ! empty( $postarr['meta_input']['gateway_payload'] ) ) {
$postarr = $this->filter_gateway_payload( $postarr, $post_id );
}
if ( ! empty( $postarr['meta_input'][ Order::$items_meta_key ] ) ) {
$postarr = $this->filter_items_input( $postarr, $post_id );
}
return $postarr;
}
/**
* Cleans up a list of Post IDs into an usable array for DB query.
*
* @since 5.1.9
*
* @param int|\WP_Post|int[]|\WP_Post[] $posts Which posts we are filtering by.
*
* @return array
*/
protected function clean_post_ids( $posts ) {
return array_unique( array_filter( array_map( static function ( $post ) {
if ( is_numeric( $post ) ) {
return $post;
}
if ( $post instanceof \WP_Post ) {
return $post->ID;
}
return null;
}, (array) $posts ) ) );
}
/**
* Filters order by whether or not it contains a given ticket/s.
*
* @since 5.1.9
*
* @param int|\WP_Post|int[]|\WP_Post[] $tickets Which tickets we are filtering by.
*
* @return null
*/
public function filter_by_tickets( $tickets = null ) {
if ( empty( $tickets ) ) {
return null;
}
$tickets = $this->clean_post_ids( $tickets );
if ( empty( $tickets ) ) {
return null;
}
$this->by( 'meta_in', Order::$tickets_in_order_meta_key, $tickets );
return null;
}
/**
* Filters order by whether or not it contains a given ticket/s.
*
* @since 5.1.9
*
* @param int|\WP_Post|int[]|\WP_Post[] $tickets Which tickets we are filtering by.
*
* @return null
*/
public function filter_by_tickets_not( $tickets = null ) {
if ( empty( $tickets ) ) {
return null;
}
$tickets = $this->clean_post_ids( $tickets );
if ( empty( $tickets ) ) {
return null;
}
$this->by( 'meta_not_in', Order::$tickets_in_order_meta_key, $tickets );
return null;
}
/**
* Filters order by whether or not it contains a given ticket/s.
*
* @since 5.1.9
*
* @param int|\WP_Post|int[]|\WP_Post[] $events Which events we are filtering by.
*
* @return null
*/
public function filter_by_events( $events = null ) {
if ( empty( $events ) ) {
return null;
}
$events = $this->clean_post_ids( $events );
if ( empty( $events ) ) {
return null;
}
$this->by( 'meta_in', Order::$events_in_order_meta_key, $events );
return null;
}
/**
* Filters order by whether or not it contains a given event/s.
*
* @since 5.1.9
*
* @param int|\WP_Post|int[]|\WP_Post[] $events Which events we are filtering by.
*
* @return null
*/
public function filter_by_events_not( $events = null ) {
if ( empty( $events ) ) {
return null;
}
$events = $this->clean_post_ids( $events );
if ( empty( $events ) ) {
return null;
}
$this->by( 'meta_not_in', Order::$events_in_order_meta_key, $events );
return null;
}
}
Changelog
| Version | Description |
|---|---|
| 5.1.9 | Introduced. |
Methods
- __construct — {@inheritdoc}
- filter_by_events — Filters order by whether or not it contains a given ticket/s.
- filter_by_events_not — Filters order by whether or not it contains a given event/s.
- filter_by_tickets — Filters order by whether or not it contains a given ticket/s.
- filter_by_tickets_not — Filters order by whether or not it contains a given ticket/s.
- filter_postarr_for_create — {@inheritdoc}
- filter_postarr_for_update — {@inheritdoc}
- handle_order_by — Handles the `order_by` clauses for events