';
echo '
' . esc_html__( 'Eventbrite for The Events Calendar', 'eb4tec' ) . '
';
// Sync status bar.
if ( $last_sync ) {
$sync_time = human_time_diff( $last_sync );
echo '';
printf(
esc_html__( 'Last sync: %s ago', 'eb4tec' ),
esc_html( $sync_time )
);
if ( is_array( $sync_result ) ) {
printf(
' — ' . esc_html__( '%d pulled, %d pushed, %d errors.', 'eb4tec' ),
(int) ( $sync_result['pulled'] ?? 0 ),
(int) ( $sync_result['pushed'] ?? 0 ),
(int) ( $sync_result['errors'] ?? 0 )
);
}
echo '
';
}
// Sync Now button.
echo '';
// Tabs.
$tabs = [
'api' => __( 'API & Credentials', 'eb4tec' ),
'sync' => __( 'Sync Settings', 'eb4tec' ),
'woocommerce' => __( 'WooCommerce', 'eb4tec' ),
];
echo '';
echo '';
echo '';
}
private function render_tab_api( string $org_name ): void {
$token = get_option( 'eb4tec_api_token', '' );
$token_display = $token ? str_repeat( '•', 20 ) : '';
$org_id = esc_attr( get_option( 'eb4tec_org_id', '' ) );
?>
|
|
|
|
|
|
__( 'Hourly', 'eb4tec' ),
'twicedaily' => __( 'Twice Daily', 'eb4tec' ),
'daily' => __( 'Daily', 'eb4tec' ),
];
$directions = [
'both' => __( 'Both directions', 'eb4tec' ),
'eb_to_tec' => __( 'Eventbrite → WordPress only', 'eb4tec' ),
'tec_to_eb' => __( 'WordPress → Eventbrite only', 'eb4tec' ),
];
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'product_cat',
'hide_empty' => false,
] );
?>
|
|
|
|
|
|
|
|
|
|
'eb4tec-settings',
'tab' => $tab,
'updated' => '1',
], admin_url( 'edit.php?post_type=tribe_events' ) );
wp_safe_redirect( $redirect );
exit;
}
public function ajax_validate_token(): void {
check_ajax_referer( 'eb4tec_admin_ajax', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'eb4tec' ) ] );
}
$token = sanitize_text_field( $_POST['token'] ?? '' );
if ( empty( $token ) ) {
wp_send_json_error( [ 'message' => __( 'No token provided.', 'eb4tec' ) ] );
}
// Temporarily update the token so the API client picks it up.
$old_token = get_option( 'eb4tec_api_token', '' );
update_option( 'eb4tec_api_token', $token, false );
$api = new EB4TEC_API_Client();
$result = $api->get_user_me();
if ( is_wp_error( $result ) ) {
update_option( 'eb4tec_api_token', $old_token, false );
wp_send_json_error( [ 'message' => $result->get_error_message() ] );
}
// Fetch organization ID.
$orgs = isset( $result['organizations'] ) ? $result['organizations'] : [];
if ( empty( $orgs ) ) {
// Try getting org from user profile.
$org_id = '';
$org_name = $result['name'] ?? '';
} else {
$org = reset( $orgs );
$org_id = $org['id'] ?? '';
$org_name = $org['name'] ?? '';
}
update_option( 'eb4tec_org_id', sanitize_text_field( $org_id ) );
update_option( 'eb4tec_org_name', sanitize_text_field( $org_name ) );
wp_send_json_success( [
'message' => sprintf( __( 'Connected as %s (Org: %s)', 'eb4tec' ), esc_html( $result['name'] ?? '' ), esc_html( $org_name ) ),
'org_id' => $org_id,
'org_name' => $org_name,
] );
}
public function ajax_register_webhook(): void {
check_ajax_referer( 'eb4tec_admin_ajax', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'eb4tec' ) ] );
}
$secret = get_option( 'eb4tec_webhook_secret', '' );
if ( empty( $secret ) ) {
$secret = wp_generate_password( 32, false );
update_option( 'eb4tec_webhook_secret', $secret );
}
$endpoint_url = add_query_arg( 'eb4tec_webhook', '1', home_url( '/' ) );
$api = new EB4TEC_API_Client();
$result = $api->create_webhook( [
'webhook' => [
'endpoint_url' => $endpoint_url,
'actions' => 'event.created,event.published,event.updated,event.unpublished,attendee.updated',
],
] );
if ( is_wp_error( $result ) ) {
wp_send_json_error( [ 'message' => $result->get_error_message() ] );
}
update_option( 'eb4tec_webhook_id', sanitize_text_field( $result['id'] ?? '' ) );
wp_send_json_success( [ 'message' => __( 'Webhook registered successfully.', 'eb4tec' ) ] );
}
public function ajax_delete_webhook(): void {
check_ajax_referer( 'eb4tec_admin_ajax', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'eb4tec' ) ] );
}
$webhook_id = get_option( 'eb4tec_webhook_id', '' );
if ( empty( $webhook_id ) ) {
wp_send_json_error( [ 'message' => __( 'No webhook ID stored.', 'eb4tec' ) ] );
}
$api = new EB4TEC_API_Client();
$result = $api->delete_webhook( $webhook_id );
if ( is_wp_error( $result ) ) {
wp_send_json_error( [ 'message' => $result->get_error_message() ] );
}
delete_option( 'eb4tec_webhook_id' );
wp_send_json_success( [ 'message' => __( 'Webhook removed.', 'eb4tec' ) ] );
}
public function admin_enqueue_scripts( string $hook ): void {
$screen = get_current_screen();
if ( ! $screen || ! str_contains( $screen->id ?? '', 'eb4tec' ) ) {
return;
}
$nonce = wp_create_nonce( 'eb4tec_admin_ajax' );
wp_add_inline_script(
'jquery',
"(function($){ const nonce = '{$nonce}';
$('#eb4tec-validate-token').on('click', function(){
var token = $('#eb4tec_api_token').val();
$.post(ajaxurl, {action:'eb4tec_validate_token',nonce:nonce,token:token}, function(r){
var el = $('#eb4tec-validate-result');
if(r.success){ el.css('color','green').text(r.data.message); $('#eb4tec_org_id').val(r.data.org_id); }
else { el.css('color','red').text(r.data.message); }
});
});
$('#eb4tec-register-webhook').on('click', function(){
$.post(ajaxurl, {action:'eb4tec_register_webhook',nonce:nonce}, function(r){
var el = $('#eb4tec-webhook-result');
if(r.success){ el.css('color','green').text(r.data.message); }
else { el.css('color','red').text(r.data.message); }
});
});
$('#eb4tec-delete-webhook').on('click', function(){
$.post(ajaxurl, {action:'eb4tec_delete_webhook',nonce:nonce}, function(r){
var el = $('#eb4tec-webhook-result');
if(r.success){ el.css('color','green').text(r.data.message); }
else { el.css('color','red').text(r.data.message); }
});
});
})(jQuery);"
);
}
public function admin_notices(): void {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$screen = get_current_screen();
if ( ! $screen || ! str_contains( $screen->id ?? '', 'eb4tec' ) ) {
return;
}
if ( ! empty( $_GET['updated'] ) ) {
echo '' .
esc_html__( 'Settings saved.', 'eb4tec' ) .
'
';
}
if ( get_transient( 'eb4tec_rate_limit_warning' ) ) {
echo '' .
esc_html__( 'Eventbrite API rate limit is nearly exhausted. Sync operations may be delayed.', 'eb4tec' ) .
'
';
}
// Show "Sync Now" result.
$user_id = get_current_user_id();
$sync_result = get_transient( "eb4tec_sync_now_result_{$user_id}" );
if ( is_array( $sync_result ) ) {
delete_transient( "eb4tec_sync_now_result_{$user_id}" );
$msg = sprintf(
__( 'Sync complete — %d pulled from Eventbrite, %d pushed to Eventbrite, %d errors.', 'eb4tec' ),
(int) ( $sync_result['pulled'] ?? 0 ),
(int) ( $sync_result['pushed'] ?? 0 ),
(int) ( $sync_result['errors'] ?? 0 )
);
$class = ( ( $sync_result['errors'] ?? 0 ) > 0 ) ? 'notice-warning' : 'notice-success';
echo '';
}
}
}