_settings = $this->_registry->get( 'model.settings' );
$this->_get_ticket_types_error = __( 'We were unable to get the Tickets Details from Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_get_tickets_error = __( 'We were unable to get the Tickets Attendees from Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_sign_up_error = __( 'We were unable to Sign you Up for Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_sign_in_error = __( 'We were unable to Sign you In for Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_create_event_error = __( 'We were unable to create the Event on Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_update_event_error = __( 'We were unable to update the Event on Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_missing_tickets_error = __( 'The event has the option Tickets selected but any ticket was added.' , AI1EC_PLUGIN_NAME );
$this->_tickets_removed_error = __( 'We were unable to remove the Tickets from Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
$this->_tickets_imported_error = __( 'This Event was replicated from another site. Any changes on Tickets were discarded.', AI1EC_PLUGIN_NAME );
$this->_save_pref_error = __( 'Payment preferences were not saved.' , AI1EC_PLUGIN_NAME );
$this->_save_pref_success = __( 'Payment preferences were saved.' , AI1EC_PLUGIN_NAME );
$this->_event_not_found_error = __( 'Event not found inside the database.' , AI1EC_PLUGIN_NAME );
$this->_get_purchases_error = __( 'We were unable to get the Sales information from Time.ly Ticketing' , AI1EC_PLUGIN_NAME );
}
/**
* Get the header array with authorization token
*/
protected function _get_headers( $with_authorizaton = true ) {
$headers = array(
'content-type' => 'application/json'
);
if ( true === $with_authorizaton ) {
$headers['Authorization'] = 'Basic ' . $this->_settings->get( 'ticketing_token' );
}
return $headers;
}
private function _count_valid_tickets( $post_ticket_types ) {
if (false === isset( $post_ticket_types ) || 0 === count( $post_ticket_types ) ) {
return 0;
} else {
$count = 0;
foreach ( $post_ticket_types as $ticket_type_ite ) {
if ( !isset( $ticket_type_ite['remove'] ) ) {
$count++;
}
}
return $count;
}
}
/**
* Create or update a Ticket Event on API server
* @return object Response body in JSON.
*/
public function store_event( Ai1ec_Event $event, WP_Post $post ) {
if ( isset( $_POST['ai1ec_tickets_loading_error'] ) ) {
//do not update tickets because is unsafe. There was a problem to load the tickets,
//the customer received the same message when the event was loaded.
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $_POST['ai1ec_tickets_loading_error'], 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return null;
}
if ( $this->is_ticket_event_imported( $event->get( 'post_id' ) ) ) {
//prevent changes on Ticket Events that were imported
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $this->_tickets_imported_error, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return null;
} else if ( false === ai1ec_is_blank( $event->get( 'ical_feed_url' ) ) ) {
//prevent ticket creating inside Regular Events that were imported
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $this->_tickets_imported_error, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return null;
}
$api_event_id = get_post_meta(
$event->get( 'post_id' ),
self::EVENT_ID_METADATA,
true
);
$is_new = ! $api_event_id;
if ( 0 === $this->_count_valid_tickets( $_POST['ai1ec_tickets'] ) ) {
$message = $this->_missing_tickets_error;
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return null;
}
$headers = $this->_get_headers();
$fields = array( 'visibility' => $_POST['visibility'] );
$body_data = $this->_parse_event_fields_to_api_structure(
$event,
$post,
$_POST['ai1ec_tickets'],
$fields
);
$url = AI1EC_API_URL . 'events';
if ( $api_event_id ) {
$url = $url . '/' . $api_event_id;
}
//get the thumbnail id saved previously
$event_thumbnail_id = get_post_meta( $event->get( 'post_id' ), self::THUMBNAIL_ID_METADATA, true );
if ( false === isset( $event_thumbnail_id ) ) {
$event_thumbnail_id = 0;
}
//get the current thumbnail id
$post_thumbnail_id = get_post_thumbnail_id( $event->get( 'post_id' ) );
if ( false === isset( $post_thumbnail_id ) ) {
$post_thumbnail_id = 0;
}
$update_image = ( $event_thumbnail_id !== $post_thumbnail_id );
$payload = '';
if ( true === $update_image && 0 < $post_thumbnail_id ) {
$boundary = wp_generate_password( 24 );
$headers['content-type'] = 'multipart/form-data; boundary=' . $boundary;
$body_data['update_image'] = '1';
foreach ($body_data as $key => $value) {
if ( is_array( $value ) ) {
$index = 0;
foreach ( $value as $ticket_type_ite ) {
foreach ( $ticket_type_ite as $child_key => $child_value ) {
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="' . $key . '[' . $index . '][' . $child_key . ']"' . "\r\n";
$payload .= "\r\n";
$payload .= $child_value;
$payload .= "\r\n";
}
$index++;
}
} else {
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n";
$payload .= "\r\n";
$payload .= $value;
$payload .= "\r\n";
}
}
$file_path = get_attached_file ( $post_thumbnail_id );
$file_type = wp_check_filetype ( $file_path );
$payload .= '--' . $boundary;
$payload .= "\r\n";
$payload .= 'Content-Disposition: form-data; name="image_id"; filename="' . basename( $file_path ) . '"' . "\r\n";
$payload .= 'Content-Type: ' . $file_type['type'] . "\r\n";
$payload .= "\r\n";
$payload .= file_get_contents( $file_path );
$payload .= "\r\n";
$payload .= '--' . $boundary . '--';
} else {
$body_data['update_image'] = (true === $update_image) ? '1' : '0';
$payload = json_encode( $body_data );
}
$request = array(
'method' => 'POST',
'headers' => $headers,
'body' => $payload,
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_request( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$response_json = json_decode( $response['body'] );
if ( $is_new && isset( $response_json->id ) ) {
update_post_meta( $event->get( 'post_id' ), self::EVENT_ID_METADATA, $response_json->id );
}
if ( $post_thumbnail_id > 0 ) {
update_post_meta( $event->get( 'post_id' ), self::THUMBNAIL_ID_METADATA, $post_thumbnail_id );
} else {
delete_post_meta( $event->get( 'post_id' ), self::THUMBNAIL_ID_METADATA );
}
return true;
} else {
$error_message = '';
if ( $is_new ) {
$error_message = $this->_transform_error_message( $this->_create_event_error, $response, $url, false );
} else {
$error_message = $this->_transform_error_message( $this->_update_event_error, $response, $url, false );
}
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $error_message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return false;
}
}
/**
* @return object Response body from API.
*/
public function save_payment_preferences() {
$calendar_id = $this->_get_ticket_calendar();
if ( 0 >= $calendar_id ) {
return null;
}
$url = AI1EC_API_URL . 'calendars/' . $calendar_id . '/payment' ;
$settings = array(
'payment_method' => $_POST['ai1ec_payment_method'],
'paypal_email' => $_POST['ai1ec_paypal_email'],
'first_name' => $_POST['ai1ec_first_name'],
'last_name' => $_POST['ai1ec_last_name'],
'street' => $_POST['ai1ec_street'],
'city' => $_POST['ai1ec_city'],
'state' => $_POST['ai1ec_state'],
'country' => $_POST['ai1ec_country'],
'postcode' => $_POST['ai1ec_postcode']
);
$headers = $this->_get_headers();
$headers['content-type'] = 'application/x-www-form-urlencoded';
$request = array(
'method' => 'PUT',
'headers' => $headers,
'body' => $settings,
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_request( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
$notification = $this->_registry->get('notification.admin');
if ( 200 !== $response_code ) {
$error_message = $this->_transform_error_message( $this->_save_pref_error, $response, AI1EC_API_URL );
$notification->store( $error_message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return false;
}else{
$notification->store( $this->_save_pref_success, 'updated', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
}
$response_json = json_decode( $response['body'] );
return $response_json;
}
/**
* @return object Response from API, or empty defaults
*/
public function get_payment_preferences() {
$calendar_id = $this->_get_ticket_calendar();
$settings = null;
if( ! empty( $calendar_id ) ) {
$request = array(
'method' => 'GET',
'headers' => $this->_get_headers(),
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_request( AI1EC_API_URL."calendars/$calendar_id/payment", $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$settings = json_decode( $response['body'] );
}
}
if ( is_null( $settings ) ) {
return (object) array('payment_method'=>'cheque', 'paypal_email'=> '', 'first_name'=>'', 'last_name'=>'', 'street'=> '', 'city'=> '', 'state'=> '', 'postcode'=> '', 'country'=> '');
} else {
return $settings;
}
}
/**
* Parse the fields of an Event to the structure used by API
*/
protected function _parse_event_fields_to_api_structure( Ai1ec_Event $event , WP_Post $post, $post_ticket_types, $api_fields_values ) {
$calendar_id = $this->_get_ticket_calendar();
if ( $calendar_id <= 0 ) {
return null;
}
//fields of ai1ec events table used by API
$body['latitude'] = $event->get( 'latitude' );
$body['longitude'] = $event->get( 'longitude' );
$body['post_id'] = $event->get( 'post_id' );
$body['calendar_id'] = $calendar_id;
$body['dtstart'] = $event->get( 'start' )->format_to_javascript();
$body['dtend'] = $event->get( 'end' )->format_to_javascript();
$body['timezone'] = $event->get( 'timezone_name' );
$body['venue_name'] = $event->get( 'venue' );
$body['address'] = $event->get( 'address' );
$body['city'] = $event->get( 'city' );
$body['province'] = $event->get( 'province' );
$body['postal_code'] = $event->get( 'postal_code' );
$body['country'] = $event->get( 'country' );
$body['contact_name'] = $event->get( 'contact_name' );
$body['contact_phone'] = $event->get( 'contact_phone' );
$body['contact_email'] = $event->get( 'contact_email' );
$body['contact_website'] = $event->get( 'contact_url' );
$body['uid'] = $event->get( 'ical_uid' );
$body['title'] = $post->post_title;
$body['description'] = $post->post_content;
$body['url'] = get_permalink( $post->ID );
$body['status'] = $post->post_status;
$body['tax_rate'] = 0;
$utc_current_time = $this->_registry->get( 'date.time')->format_to_javascript();
$body['created_at'] = $utc_current_time;
$body['updated_at'] = $utc_current_time;
//removing blank values
foreach ($body as $key => $value) {
if ( ai1ec_is_blank( $value ) ) {
unset( $body[ $key ] );
}
}
if ( null !== $api_fields_values && is_array( $api_fields_values )) {
foreach ($api_fields_values as $key => $value) {
$body[$key] = $api_fields_values[$key];
if ( 'visibility' === $key ) {
if ( 0 === strcasecmp( 'private', $value ) ) {
$body['status'] = 'private';
} else if ( 0 === strcasecmp( 'password', $value ) ) {
$body['status'] = 'password';
}
}
}
}
$tickets_types = array();
if ( isset( $post_ticket_types )) {
$index = 0;
foreach ( $post_ticket_types as $ticket_type_ite ) {
$tickets_types[$index++] = $this->_parse_tickets_type_post_to_api_structure(
$ticket_type_ite,
$event
);
}
}
$body['ticket_types'] = $tickets_types;
return $body;
}
/**
* Parse the fields of a Ticket Type to the structure used by API
*/
protected function _parse_tickets_type_post_to_api_structure( $ticket_type_ite, $event ) {
$utc_current_time = $this->_registry->get( 'date.time' )->format_to_javascript();
if ( isset( $ticket_type_ite['id'] ) ) {
$ticket_type['id'] = $ticket_type_ite['id'];
$ticket_type['created_at'] = $ticket_type_ite['created_at'];
} else {
$ticket_type['created_at'] = $utc_current_time;
}
if ( isset( $ticket_type_ite['remove'] ) ) {
$ticket_type['deleted_at'] = $utc_current_time;
}
$ticket_type['name'] = $ticket_type_ite['ticket_name'];
$ticket_type['description'] = $ticket_type_ite['description'];
$ticket_type['price'] = $ticket_type_ite['ticket_price'];
if ( 0 === strcasecmp( 'on', $ticket_type_ite['unlimited'] ) ) {
$ticket_type['quantity'] = null;
} else {
$ticket_type['quantity'] = $ticket_type_ite['quantity'];
}
$ticket_type['buy_min_qty'] = $ticket_type_ite['buy_min_limit'];
if ( ai1ec_is_blank( $ticket_type_ite['buy_max_limit'] ) ) {
$ticket_type['buy_max_qty'] = null;
} else {
$ticket_type['buy_max_qty'] = $ticket_type_ite['buy_max_limit'];
}
if ( 0 === strcasecmp( 'on', $ticket_type_ite['availibility'] ) ) {
//immediate availability
$timezone_start_time = $this->_registry->get( 'date.time' );
$timezone_start_time->set_timezone( $event->get('timezone_name') );
$ticket_type['sale_start_date'] = $timezone_start_time->format_to_javascript( $event->get('timezone_name') );
$ticket_type['sale_end_date'] = $event->get( 'end' )->format_to_javascript();
} else {
$ticket_type['sale_start_date'] = $ticket_type_ite['ticket_sale_start_date'];
$ticket_type['sale_end_date'] = $ticket_type_ite['ticket_sale_end_date'];
}
$ticket_type['updated_at'] = $utc_current_time;
$ticket_type['status'] = $ticket_type_ite['ticket_status'];
return $ticket_type;
}
/**
* Unparse the fields of API structure to the Ticket Type
*/
protected function _unparse_tickets_type_from_api_structure( $ticket_type_api ) {
$ticket_type = $ticket_type_api;
$ticket_type->ticket_name = $ticket_type_api->name;
$ticket_type->ticket_price = $ticket_type_api->price;
$ticket_type->buy_min_limit = $ticket_type_api->buy_min_qty;
if ( null === $ticket_type_api->buy_max_qty ) {
$ticket_type->buy_max_limit = self::MAX_TICKET_TO_BUY_DEFAULT;
} else {
$ticket_type->buy_max_limit = $ticket_type_api->buy_max_qty;
}
$ticket_type->ticket_sale_start_date = $ticket_type_api->sale_start_date; //YYYY-MM-YY HH:NN:SS
$ticket_type->ticket_sale_end_date = $ticket_type_api->sale_end_date; //YYYY-MM-YY HH:NN:SS
$ticket_type->ticket_status = $ticket_type_api->status;
if ( false === isset( $ticket_type_api->quantity ) ||
null === $ticket_type_api->quantity ) {
$ticket_type->unlimited = 'on';
} else {
$ticket_type->unlimited = 'off';
}
$ticket_type->ticket_type_id = $ticket_type_api->id;
$ticket_type->available = $ticket_type_api->available;
$ticket_type->availability = $this->_parse_availability_message( $ticket_type_api->availability );
//derived property to set the max quantity of dropdown
if ( $ticket_type->available !== null ) {
if ( $ticket_type->available > $ticket_type->buy_max_limit ) {
$ticket_type->buy_max_available = $ticket_type->buy_max_limit;
} else {
$ticket_type->buy_max_available = $ticket_type->available;
}
} else {
$ticket_type->buy_max_available = $ticket_type->buy_max_limit;
}
return $ticket_type;
}
public function _parse_availability_message( $availability ){
if ( ai1ec_is_blank ( $availability ) ) {
return null;
} else {
switch ($availability) {
case 'past_event':
return __( 'Past Event' );
case 'event_closed':
return __( 'Event closed' );
case 'not_available_yet':
return __( 'Not available yet' );
case 'sale_closed':
return __( 'Sale closed' );
case 'sold_out':
return __( 'Sold out' );
default:
return __( 'Not available' );
}
}
}
/**
* @return string JSON.
*/
public function get_ticket_types( $post_id ) {
$api_event_id = get_post_meta(
$post_id,
Ai1ec_Api::EVENT_ID_METADATA,
true
);
if ( ! $api_event_id ) {
return json_encode( array( 'data' => array() ) );
}
$request = array(
'headers' => $this->_get_headers(),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = $this->get_api_url( $post_id ) . 'events/' . $api_event_id . '/ticket_types';
$response = wp_remote_get( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$result = json_decode( $response['body'] );
if ( isset( $result->ticket_types ) ) {
foreach ( $result->ticket_types as $ticket_api ) {
$this->_unparse_tickets_type_from_api_structure( $ticket_api );
}
return json_encode( array( 'data' => $result->ticket_types ) );
} else {
return json_encode( array( 'data' => array() ) );
}
} else {
$error_message = $this->_transform_error_message( $this->_get_ticket_types_error, $response, $url, true );
return json_encode( array( 'data' => array(), 'error' => $error_message ) );
}
}
/**
* @return object Response body in JSON.
*/
public function get_tickets( $post_id ) {
$api_event_id = get_post_meta(
$post_id,
Ai1ec_Api::EVENT_ID_METADATA,
true
);
if ( ! $api_event_id ) {
return json_encode( array( 'data' => array() ) );
}
$request = array(
'headers' => $this->_get_headers(),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = $this->get_api_url( $post_id ) . 'events/' . $api_event_id . '/tickets';
$response = wp_remote_get( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
return $response['body'];
} else {
$error_message = $this->_transform_error_message( $this->_get_tickets_error, $response, $url, true );
return json_encode( array( 'data' => array(), 'error' => $error_message ) );
}
}
public function _order_comparator( $order1, $order2 ) {
return strcmp( $order1->created_at, $order2->created_at ) * -1;
}
/**
* @return object Response body in JSON.
*/
public function get_purchases() {
$request = array(
'headers' => $this->_get_headers(),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = AI1EC_API_URL . 'calendars/' . $this->_get_ticket_calendar() . '/sales';
$response = wp_remote_get( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$result = json_decode( $response['body'] );
if ( isset( $result->orders ) ) {
usort( $result->orders, array( "Ai1ec_Api", "_order_comparator" ) );
return $result->orders;
} else {
return array();
}
} else {
$error_message = $this->_transform_error_message( $this->_get_purchases_error, $response, $url, true );
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $error_message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return array();
}
}
public function is_ticket_event_imported( $post_id ) {
//if the event is imported, the ICS added the api url on metadata information
$api_url = get_post_meta(
$post_id,
Ai1ec_Api::ICS_API_URL_METADATA,
true
);
return (false === ai1ec_is_blank ( $api_url ));
}
protected function get_api_url ( $post_id ) {
//if the event is imported, the ICS added the api url on metadata informatino
$api_url = get_post_meta(
$post_id,
Ai1ec_Api::ICS_API_URL_METADATA,
true
);
if ( ai1ec_is_blank ( $api_url ) ) {
return AI1EC_API_URL;
} else {
return $api_url;
}
}
/**
* Clean the ticketing settings on WP database only
*/
public function signout() {
$this->_save_settings( '', false, '', 0 );
return array( 'message' => '');
}
private function _save_settings( $message, $enabled, $token, $calendar_id ) {
$this->_settings->set( 'ticketing_message' , $message );
$this->_settings->set( 'ticketing_enabled' , $enabled );
$this->_settings->set( 'ticketing_token' , $token );
$this->_settings->set( 'ticketing_calendar_id', $calendar_id );
}
/**
* @return object Response body in JSON.
*/
public function signin() {
$body['email'] = $_POST['ai1ec_email'];
$body['password'] = $_POST['ai1ec_password'];
$request = array(
'headers' => $this->_get_headers( false ),
'body' => json_encode( $body ),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = AI1EC_API_URL . 'auth/authenticate';
$response = wp_remote_post( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$response_body = json_decode( $response['body'], true );
$this->_save_settings( $response_body['message'], true, $response_body['auth_token'], $this->_find_user_calendar() );
} else {
$error_message = $this->_transform_error_message( $this->_sign_in_error, $response, AI1EC_API_URL );
$this->_save_settings( $error_message, false, '', 0 );
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $error_message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
}
}
/**
* @return object Response body in JSON.
*/
public function signup() {
$body['name'] = $_POST['ai1ec_name'];
$body['email'] = $_POST['ai1ec_email'];
$body['password'] = $_POST['ai1ec_password'];
$body['password_confirmation'] = $_POST['ai1ec_password_confirmation'];
$body['phone'] = $_POST['ai1ec_phone'];
$body['terms'] = $_POST['ai1ec_terms'];
$request = array(
'headers' => $this->_get_headers( false ),
'body' => json_encode( $body ),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = AI1EC_API_URL . 'auth/register';
$response = wp_remote_post( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$response_body = json_decode( $response['body'], true );
$this->_save_settings( $response_body['Registration'], true, $response_body['auth_token'] , $this->_create_calendar() );
} else {
$error_message = $this->_transform_error_message( $this->_sign_up_error, $response, AI1EC_API_URL );
$this->_save_settings( $error_message, false, '', 0 );
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $error_message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
}
}
/**
* Create a standarized message to return
* 1) If the API respond with http code 400 and with a JSON body, so, we will consider the API message to append in the base message.
* 2) If the API does not responde with http code 400 or does not have a valid a JSON body, we will show the API URL and the http message error.
*/
protected function _transform_error_message( $base_message, $response, $url, $ask_for_reload = false ) {
$http_response_code = wp_remote_retrieve_response_code( $response );
$api_error = $this->_get_api_error_msg( $response );
$result = null;
if ( false === ai1ec_is_blank( $api_error ) ) {
$result = sprintf(
__( '%s.
Detail: %s.', AI1EC_PLUGIN_NAME ),
$base_message, $api_error
);
} else {
$error_message = sprintf(
__( 'API URL: %s.
Detail: %s - %s', AI1EC_PLUGIN_NAME ),
$url,
wp_remote_retrieve_response_code( $response ),
wp_remote_retrieve_response_message( $response )
);
$mailto = 'betasupport@time.ly';
if ( true === $ask_for_reload ) {
$result = sprintf(
__( '%s. Please reload this page to try again. If this error persists, please contact us at %s. In your report please include the information below.
%s.', AI1EC_PLUGIN_NAME ),
$base_message,
$mailto,
$error_message
);
} else {
$result = sprintf(
__( '%s. Please try again. If this error persists, please contact us at %s. In your report please include the information below.
%s.', AI1EC_PLUGIN_NAME ),
$base_message,
$mailto,
$error_message
);
}
}
$result = trim( $result );
$result = str_replace( '..', '.', $result );
$result = str_replace( '.,', '.', $result );
return $result;
}
/**
* Search for the API message error
*/
protected function _get_api_error_msg( $response ) {
if ( isset( $response ) && false === is_wp_error( $response ) ) {
$response_body = json_decode( $response['body'], true );
if ( json_last_error() === JSON_ERROR_NONE &&
isset( $response_body ) &&
isset( $response_body['errors'] ) ) {
$errors = $response_body['errors'];
if ( false === is_array( $errors )) {
$errors = array( $errors );
}
$messages = null;
foreach ($errors as $key => $value) {
if ( false === ai1ec_is_blank( $value ) ) {
if ( is_array( $value ) ) {
$value = implode ( ', ', $value );
}
$messages[] = $value;
}
}
if ( null !== $messages && false === empty( $messages ) ) {
return implode ( ', ', $messages);
}
}
}
return null;
}
/**
* Check if the response that came from the API is the event not found
*/
private function _is_event_notfound_error( $response_code, $response ) {
if ( 404 === $response_code ) {
if ( isset( $response['body'] ) ) {
$response_body = json_decode( $response['body'], true );
if ( json_last_error() === JSON_ERROR_NONE &&
$response_body &&
isset( $response_body['message'] ) ) {
if ( false !== stripos( $response_body['message'], 'event not found') ) {
return true;
}
}
}
}
return false;
}
/**
* Get the ticket calendar from settings, if the calendar does not exists in
* settings, then we will try to find on the API
* @return string JSON.
*/
protected function _get_ticket_calendar() {
$ticketing_calendar_id = $this->_settings->get( 'ticketing_calendar_id' );
if ( isset( $ticketing_calendar_id ) && $ticketing_calendar_id > 0) {
return $ticketing_calendar_id;
} else {
//if the calendar is not saved on settings it should exists on API
$ticketing_calendar_id = $this->_find_user_calendar();
if ( $ticketing_calendar_id > 0 ) {
$this->_settings->set( 'ticketing_calendar_id', $ticketing_calendar_id );
return $ticketing_calendar_id;
} else {
//if the calendar should not exist on API, we will created
$ticketing_calendar_id = $this->_create_calendar();
if ( $ticketing_calendar_id > 0 ) {
$this->_settings->set( 'ticketing_calendar_id', $ticketing_calendar_id );
} else {
return 0;
}
}
}
}
/**
* Find the existent calendar when the user is signing in
*/
protected function _find_user_calendar() {
$body = array(
'title' => get_bloginfo( 'name' )
);
$request = array(
'headers' => $this->_get_headers(),
'body' => json_encode( $body ),
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_get( AI1EC_API_URL . 'calendars', $request );
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = json_decode( $response['body'] );
if ( 200 === $response_code ) {
if ( is_array( $response_body ) ) {
return $response_body[0]->id;
} else {
return $response_body->id;
}
} else {
return 0;
}
}
/**
* Create a calendar when the user is signup
*/
protected function _create_calendar() {
$body = array(
'title' => get_bloginfo( 'name' ),
'url' => ai1ec_site_url(),
'timezone' => $this->_settings->get( 'timezone_string' )
);
$request = array(
'headers' => $this->_get_headers(),
'body' => json_encode( $body ),
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_post( AI1EC_API_URL . 'calendars', $request );
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = json_decode( $response['body'] );
if ( 200 === $response_code ) {
return $response_body->id;
} else {
return 0;
}
}
/**
* @return NULL in case of success or an error string in case of error
*/
public function update_api_event_fields( WP_Post $post, $api_fields_values ) {
$post_id = $post->ID;
$api_event_id = get_post_meta(
$post_id,
self::EVENT_ID_METADATA,
true
);
if ( ! $api_event_id ) {
return null;
}
if ( $this->is_ticket_event_imported( $post_id ) ) {
return null;
}
//updating the event status
try {
$event = $this->_registry->get(
'model.event',
$post_id ? $post_id : null
);
} catch ( Ai1ec_Event_Not_Found_Exception $excpt ) {
$message = $this->_event_not_found_error;
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return $message;
}
$headers = $this->_get_headers();
$body_data = $this->_parse_event_fields_to_api_structure(
$event,
$post,
null, //does not update ticket types, just chaging the api fields specified
$api_fields_values
);
$url = AI1EC_API_URL . 'events' . '/' . $api_event_id;
$request = array(
'method' => 'POST',
'headers' => $headers,
'body' => json_encode( $body_data ),
'timeout' => self::DEFAULT_TIMEOUT
);
$response = wp_remote_request( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 !== $response_code ) {
if ( $this->_is_event_notfound_error( $response_code, $response ) ) {
if ( isset( $api_fields_values['status'] ) &&
'trash' === $api_fields_values['status'] ) {
//this is an exception, the event was deleted on API server, but for some reason
//the metada EVENT_ID_METADATA was not unset, in this case leave the event be
//move to trash
return null;
}
}
$message = $this->_transform_error_message( $this->_update_event_error, $response, $url, true );
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return $message;
} else {
return null;
}
}
/**
* Deletes the API event
* @return NULL in case of success or an error string in case of error
*/
public function delete_api_event( $post_id ) {
if ( $this->is_ticket_event_imported( $post_id ) ) {
$this->clear_event_metadata( $post_id );
return null;
}
$api_event_id = get_post_meta(
$post_id,
self::EVENT_ID_METADATA,
true
);
if ( ! $api_event_id ) {
return null;
}
$request = array(
'method' => 'DELETE',
'headers' => $this->_get_headers(),
'timeout' => self::DEFAULT_TIMEOUT
);
$url = AI1EC_API_URL . 'events/' . $api_event_id;
$response = wp_remote_request( $url, $request );
$response_code = wp_remote_retrieve_response_code( $response );
if ( 200 === $response_code ) {
$this->clear_event_metadata( $post_id );
return null;
} else {
if ( $this->_is_event_notfound_error( $response_code, $response ) ) {
//this is an exception, the event was deleted on API server, but for some reason
//the metada EVENT_ID_METADATA was not unset, in this case leave the event be
//move to trash
return null;
}
$message = $this->_transform_error_message( $this->_tickets_removed_error, $response, $url, true );
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $message, 'error', 0, array( Ai1ec_Notification_Admin::RCPT_ADMIN ), false );
return $message;
}
}
/**
* Clear the event metadata used by Event from the post id
*/
public function clear_event_metadata( $post_id ) {
delete_post_meta( $post_id, self::EVENT_ID_METADATA );
delete_post_meta( $post_id, self::THUMBNAIL_ID_METADATA );
delete_post_meta( $post_id, self::ICS_CHECKOUT_URL_METADATA );
delete_post_meta( $post_id, self::ICS_API_URL_METADATA );
}
public function create_checkout_url( $api_event_id , $url_checkout = AI1EC_TICKETS_CHECKOUT_URL) {
return str_replace( '{event_id}', $api_event_id, $url_checkout );
}
/**
* Check if the current WP instance is signed into the API
*/
public function is_signed() {
return true === $this->_settings->get( 'ticketing_enabled' );
}
/**
* Get the last message return by Signup or Signup process
*/
public function get_sign_message() {
return $this->_settings->get( 'ticketing_message' );
}
/**
* Clear the last message return by Signup or Signup process
*/
public function clear_sign_message() {
return $this->_settings->set( 'ticketing_message', '' );
}
}