1, 'event_id' => $event_id, 'installation_id' => (string) $installation['installation_id'], 'event_name' => $name, 'occurred_at' => time(), 'plugin_version' => abtestkit_hosted_sync_plugin_version(), 'test_ref' => null, 'payload' => array( 'evidence' => 'observed' ), ); if ( is_wp_error( ABTestKit_Connected_Event::validate( $event, time() ) ) ) { return new WP_Error( 'abtestkit_connected_onboarding_event_invalid' ); } add_option( $key, array( 'event' => $event, 'acknowledged' => false ), '', 'no' ); $marker = get_option( $key, null ); return is_array( $marker ) ? $marker : new WP_Error( 'abtestkit_connected_onboarding_reservation_failed' ); } /** Retry the exact envelope until accepted, or report its expiry honestly. */ function abtestkit_connected_onboarding_queue_marker( string $key, array $marker ) : bool { if ( ! is_bool( $marker['acknowledged'] ?? null ) || ! is_array( $marker['event'] ?? null ) ) { abtestkit_connected_collection_gap( 'onboarding_marker_invalid' ); return false; } if ( $marker['acknowledged'] || ! empty( $marker['expired'] ) ) { return true; } if ( (int) ( $marker['event']['occurred_at'] ?? 0 ) <= time() - ABTestKit_Connected_Event::MAX_AGE ) { $marker['expired'] = true; update_option( $key, $marker, false ); abtestkit_connected_collection_gap( 'onboarding_expired' ); return false; } if ( 1 !== (int) get_option( ABTestKit_Connected_Outbox::SCHEMA_OPTION, 0 ) ) { $installed = ABTestKit_Connected_Outbox::install(); if ( is_wp_error( $installed ) ) { abtestkit_connected_collection_gap( $installed->get_error_code() ); return false; } } $queued = ABTestKit_Connected_Outbox::enqueue( $marker['event'], time() ); if ( is_wp_error( $queued ) ) { abtestkit_connected_collection_gap( $queued->get_error_code() ); return false; } return true; } /** First connected, eligible opening of the create-test wizard with no tests. */ function abtestkit_connected_onboarding_attempt() : void { if ( ! current_user_can( 'manage_options' ) || ! abtestkit_connected_platform_can_create_or_launch() ) { return; } $tests = get_option( 'abtestkit_page_tests', array() ); if ( ! is_array( $tests ) || $tests ) { return; } abtestkit_connected_onboarding_observe( 'onboarding_started' ); } /** First confirmed test creation, not a browser submit or shadow draft. */ function abtestkit_connected_onboarding_complete_after_test_created( string $test_id ) : void { if ( ! current_user_can( 'manage_options' ) || ! abtestkit_connected_platform_can_create_or_launch() ) { return; } $tests = get_option( 'abtestkit_page_tests', array() ); if ( ! is_array( $tests ) || 1 !== count( $tests ) ) { return; } $saved_test = reset( $tests ); if ( ! is_array( $saved_test ) || (string) ( $saved_test['id'] ?? '' ) !== $test_id ) { return; } abtestkit_connected_onboarding_observe( 'onboarding_completed' ); } function abtestkit_connected_onboarding_observe( string $name ) : void { if ( ! in_array( $name, array( 'onboarding_started', 'onboarding_completed' ), true ) ) { return; } $connection = abtestkit_hosted_get_connection(); if ( ! is_array( $connection ) ) { return; } $site_ref = (string) $connection['site_ref']; $key = abtestkit_connected_onboarding_event_key( $site_ref, $name ); $marker = abtestkit_connected_onboarding_reserve( $site_ref, $name ); if ( is_wp_error( $marker ) ) { abtestkit_connected_collection_gap( $marker->get_error_code() ); return; } if ( ! is_array( $marker ) ) { abtestkit_connected_collection_gap( 'onboarding_marker_invalid' ); return; } abtestkit_connected_onboarding_queue_marker( $key, $marker ); } /** Recover pending one-shot events after queue loss or same-site reconnect. */ function abtestkit_connected_onboarding_reconcile() : void { if ( ! abtestkit_connected_platform_can_create_or_launch() ) { return; } $connection = abtestkit_hosted_get_connection(); if ( ! is_array( $connection ) ) { return; } foreach ( array( 'onboarding_started', 'onboarding_completed' ) as $name ) { $key = abtestkit_connected_onboarding_event_key( (string) $connection['site_ref'], $name ); $marker = get_option( $key, null ); if ( is_array( $marker ) && empty( $marker['acknowledged'] ) && empty( $marker['expired'] ) ) { abtestkit_connected_onboarding_queue_marker( $key, $marker ); } elseif ( null !== $marker && ! is_array( $marker ) ) { abtestkit_connected_collection_gap( 'onboarding_marker_invalid' ); } } } /** Only a complete hosted response and local outbox acknowledgement finishes it. */ function abtestkit_connected_onboarding_mark_acknowledged( array $event, string $site_ref ) : void { $name = (string) ( $event['event_name'] ?? '' ); if ( ! in_array( $name, array( 'onboarding_started', 'onboarding_completed' ), true ) ) { return; } $key = abtestkit_connected_onboarding_event_key( $site_ref, $name ); $marker = get_option( $key, null ); if ( ! is_array( $marker ) || ! hash_equals( (string) ( $marker['event']['event_id'] ?? '' ), (string) ( $event['event_id'] ?? '' ) ) ) { abtestkit_connected_collection_gap( 'onboarding_ack_marker_missing' ); return; } $marker['acknowledged'] = true; update_option( $key, $marker, false ); if ( get_option( $key, null ) !== $marker ) { abtestkit_connected_collection_gap( 'onboarding_ack_write_failed' ); } }