$event, 'client_ts' => gmdate( 'Y-m-d\TH:i:s\Z' ), ); if ( 'deactivated' === $event && '' !== $reason ) { $entry['reason'] = $reason; if ( 'other' === $reason && '' !== $reason_text ) { $entry['reason_text'] = wp_html_excerpt( sanitize_textarea_field( $reason_text ), 500, '' ); } } $events[] = $entry; update_option( 'aybabtu_sync_event_queue', array_slice( $events, -50 ), false ); } /** * Send queued setup events only after an administrator opts in. * * @param bool $blocking Whether to wait for the request. * @return void */ function aybabtu_sync_flush_events( $blocking = false ) { if ( 1 !== (int) get_option( 'aybabtu_sync_telemetry_optin', 0 ) ) { return; } $events = get_option( 'aybabtu_sync_event_queue', array() ); if ( ! is_array( $events ) || empty( $events ) ) { return; } $payload = array( 'site_hash' => aybabtu_sync_site_hash(), 'plugin_version' => AYBABTU_SYNC_VERSION, 'events' => array_values( $events ), ); $response = wp_remote_post( trailingslashit( aybabtu_sync_api_base() ) . 'api/plugin/events', array( 'timeout' => 10, 'redirection' => 0, 'blocking' => (bool) $blocking, 'headers' => array( 'Accept' => 'application/json', 'Content-Type' => 'application/json' ), 'body' => wp_json_encode( $payload ), ) ); if ( ! is_wp_error( $response ) ) { delete_option( 'aybabtu_sync_event_queue' ); } } /** * Register the in-admin key setup page. * * @return void */ function aybabtu_sync_register_key_page() { $GLOBALS['aybabtu_sync_key_hook_suffix'] = add_submenu_page( 'aybabtu-sync', __( 'Get your key', 'aybabtu-sync' ), __( 'Get your key', 'aybabtu-sync' ), 'manage_options', 'aybabtu-sync-get-key', 'aybabtu_sync_render_key_page' ); } add_action( 'admin_menu', 'aybabtu_sync_register_key_page', 99 ); /** * Render the in-admin account setup page. * * @return void */ function aybabtu_sync_render_key_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to view this page.', 'aybabtu-sync' ) ); } aybabtu_sync_queue_event( 'key_screen_opened' ); aybabtu_sync_flush_events(); $user_id = get_current_user_id(); $state = get_transient( 'aybabtu_sync_signup_state_' . $user_id ); if ( ! is_array( $state ) ) { $state = array(); } $email = isset( $state['email'] ) ? $state['email'] : sanitize_email( get_option( 'admin_email', '' ) ); ?>
__( 'Enter a valid email address and try again.', 'aybabtu-sync' ) ) ); aybabtu_sync_redirect_key_page(); } update_option( 'aybabtu_sync_telemetry_optin', 1, false ); $response = wp_remote_post( trailingslashit( aybabtu_sync_api_base() ) . 'api/plugin/signup/start', array( 'timeout' => 10, 'redirection' => 0, 'headers' => array( 'Accept' => 'application/json', 'Content-Type' => 'application/json' ), 'body' => wp_json_encode( array( 'email' => strtolower( $email ), 'site_hash' => aybabtu_sync_site_hash(), 'plugin_version' => AYBABTU_SYNC_VERSION ) ), ) ); if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { aybabtu_sync_set_signup_state( array( 'email' => $email, 'error' => __( 'AYBABTU could not be reached. Check your connection and try again.', 'aybabtu-sync' ) ) ); aybabtu_sync_flush_events(); aybabtu_sync_redirect_key_page(); } $payload = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $payload ) || empty( $payload['ok'] ) ) { aybabtu_sync_set_signup_state( array( 'email' => $email, 'error' => __( 'The code could not be sent. Try again in a moment.', 'aybabtu-sync' ) ) ); aybabtu_sync_flush_events(); aybabtu_sync_redirect_key_page(); } aybabtu_sync_set_signup_state( array( 'email' => $email, 'stage' => 'verify' ) ); aybabtu_sync_queue_event( 'code_sent' ); aybabtu_sync_flush_events(); aybabtu_sync_redirect_key_page(); } add_action( 'admin_post_aybabtu_sync_start_signup', 'aybabtu_sync_start_signup' ); /** * Verify an email code and save the issued API key. * * @return void */ function aybabtu_sync_verify_signup() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to verify account setup.', 'aybabtu-sync' ) ); } check_admin_referer( 'aybabtu_sync_verify_signup' ); $state = get_transient( 'aybabtu_sync_signup_state_' . get_current_user_id() ); $email = is_array( $state ) && isset( $state['email'] ) ? sanitize_email( $state['email'] ) : ''; $code = isset( $_POST['code'] ) && is_string( $_POST['code'] ) ? sanitize_text_field( wp_unslash( $_POST['code'] ) ) : ''; if ( ! is_email( $email ) || ! preg_match( '/^[0-9]{6}$/', $code ) ) { aybabtu_sync_set_signup_state( array( 'email' => $email, 'stage' => 'verify', 'error' => __( 'Enter the six-digit code from your email.', 'aybabtu-sync' ) ) ); aybabtu_sync_redirect_key_page(); } $response = wp_remote_post( trailingslashit( aybabtu_sync_api_base() ) . 'api/plugin/signup/verify', array( 'timeout' => 10, 'redirection' => 0, 'headers' => array( 'Accept' => 'application/json', 'Content-Type' => 'application/json' ), 'body' => wp_json_encode( array( 'email' => strtolower( $email ), 'code' => $code, 'site_hash' => aybabtu_sync_site_hash() ) ), ) ); $payload = is_wp_error( $response ) ? array() : json_decode( wp_remote_retrieve_body( $response ), true ); $key = is_array( $payload ) && isset( $payload['api_key'] ) && is_string( $payload['api_key'] ) ? $payload['api_key'] : ''; if ( 200 !== ( is_wp_error( $response ) ? 0 : (int) wp_remote_retrieve_response_code( $response ) ) || ! preg_match( '/^ay_(live|test)_[A-Za-z0-9_-]{32,}$/', $key ) ) { aybabtu_sync_set_signup_state( array( 'email' => $email, 'stage' => 'verify', 'error' => __( 'That code could not be verified. Check it and try again, or resend a code.', 'aybabtu-sync' ) ) ); aybabtu_sync_redirect_key_page(); } update_option( 'aybabtu_auth_token', aybabtu_sync_sanitize_key( $key ), false ); aybabtu_sync_set_signup_state( array( 'success' => 1 ) ); aybabtu_sync_flush_events(); aybabtu_sync_redirect_key_page(); } add_action( 'admin_post_aybabtu_sync_verify_signup', 'aybabtu_sync_verify_signup' ); /** * Save temporary setup state for the current administrator. * * @param array $state Setup state. * @return void */ function aybabtu_sync_set_signup_state( $state ) { set_transient( 'aybabtu_sync_signup_state_' . get_current_user_id(), $state, 30 * MINUTE_IN_SECONDS ); } /** * Redirect to the key setup page. * * @return void */ function aybabtu_sync_redirect_key_page() { wp_safe_redirect( admin_url( 'admin.php?page=aybabtu-sync-get-key' ) ); exit; } /** * Queue and send the first successful stock-sync milestone once. * * @return void */ function aybabtu_sync_record_first_sync() { if ( get_option( 'aybabtu_sync_first_sync_queued', false ) ) { return; } update_option( 'aybabtu_sync_first_sync_queued', 1, false ); aybabtu_sync_queue_event( 'first_sync' ); aybabtu_sync_flush_events(); } /** * Record a key-saved event after a non-empty API key is added or changed. * * @param mixed $old_value Previous API key. * @param mixed $new_value New API key. * @return void */ function aybabtu_sync_key_saved( $old_value, $new_value ) { if ( ! is_string( $new_value ) || '' === trim( $new_value ) || $new_value === $old_value ) { return; } aybabtu_sync_queue_event( 'key_saved' ); aybabtu_sync_flush_events(); } add_action( 'update_option_aybabtu_auth_token', 'aybabtu_sync_key_saved', 10, 2 ); /** * Record the first saved API key when the option is initially created. * * @param string $option Option name. * @param mixed $value Saved value. * @return void */ function aybabtu_sync_key_added( $option, $value ) { if ( 'aybabtu_auth_token' === $option ) { aybabtu_sync_key_saved( '', $value ); } } add_action( 'add_option_aybabtu_auth_token', 'aybabtu_sync_key_added', 10, 2 ); /** * Enqueue the opt-in deactivation prompt on the plugins screen. * * @param string $hook_suffix Current admin page hook. * @return void */ function aybabtu_sync_enqueue_deactivation_prompt( $hook_suffix ) { if ( 'plugins.php' !== $hook_suffix || ! current_user_can( 'manage_options' ) || 1 !== (int) get_option( 'aybabtu_sync_telemetry_optin', 0 ) ) { return; } wp_enqueue_style( 'aybabtu-sync-deactivation', plugins_url( 'assets/css/deactivation.css', AYBABTU_SYNC_FILE ), array(), AYBABTU_SYNC_VERSION ); $deactivation_script = file_get_contents( AYBABTU_SYNC_DIR . 'assets/js/deactivation.js' ); if ( false === $deactivation_script ) { return; } $deactivation_config = array( 'plugin' => plugin_basename( AYBABTU_SYNC_FILE ), 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'aybabtu_sync_deactivation' ), 'title' => __( 'Why are you deactivating AYBABTU Sync?', 'aybabtu-sync' ), 'reasons' => array( "couldn't_get_key" => __( "Couldn't get a key", 'aybabtu-sync' ), 'too_confusing' => __( 'Too confusing', 'aybabtu-sync' ), 'missing_supplier' => __( 'Missing my supplier', 'aybabtu-sync' ), 'just_testing' => __( 'Just testing', 'aybabtu-sync' ), 'other' => __( 'Other', 'aybabtu-sync' ), ), 'skip' => __( 'Skip & deactivate', 'aybabtu-sync' ), 'submit' => __( 'Send reason & deactivate', 'aybabtu-sync' ), 'cancel' => __( 'Cancel', 'aybabtu-sync' ), ); $deactivation_inline_script = 'window.aybabtuSyncDeactivation = ' . wp_json_encode( $deactivation_config, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ) . ";\n" . $deactivation_script; wp_add_inline_script( 'jquery-core', $deactivation_inline_script, 'after' ); } add_action( 'admin_enqueue_scripts', 'aybabtu_sync_enqueue_deactivation_prompt' ); /** * Store and send a deactivation reason submitted by the administrator. * * @return void */ function aybabtu_sync_record_deactivation_ajax() { check_ajax_referer( 'aybabtu_sync_deactivation', 'nonce' ); if ( ! current_user_can( 'manage_options' ) || 1 !== (int) get_option( 'aybabtu_sync_telemetry_optin', 0 ) ) { wp_send_json_error( array( 'message' => __( 'The setup event could not be sent.', 'aybabtu-sync' ) ), 403 ); } $reason = isset( $_POST['reason'] ) && is_string( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : ''; $reason_text = isset( $_POST['reason_text'] ) && is_string( $_POST['reason_text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['reason_text'] ) ) : ''; $allowed = array( "couldn't_get_key", 'too_confusing', 'missing_supplier', 'just_testing', 'other' ); if ( ! in_array( $reason, $allowed, true ) || strlen( $reason_text ) > 2000 || ( 'other' !== $reason && '' !== $reason_text ) ) { wp_send_json_error( array( 'message' => __( 'Choose a valid reason.', 'aybabtu-sync' ) ), 400 ); } aybabtu_sync_queue_event( 'deactivated', $reason, $reason_text ); aybabtu_sync_flush_events( true ); wp_send_json_success(); } add_action( 'wp_ajax_aybabtu_sync_record_deactivation', 'aybabtu_sync_record_deactivation_ajax' );