'; echo '

' . esc_html__( 'Formlyx', 'formlyx-forms' ) . '

'; self::render_notice( $notice ); if ( ! ClientRegistration::is_allowed_callback( ClientRegistration::callback_url() ) ) { echo '

' . esc_html__( 'This site needs HTTPS before it can connect to Formlyx. Local development can use HTTP on localhost.', 'formlyx-forms' ) . '

'; } echo '
'; if ( ! $connected ) { self::render_disconnected(); } else { self::render_connected( $connection ); } echo '
'; } /** * Start the Formlyx connection. * * @since 1.0.0 * * @return void */ public static function handle_connect(): void { self::require_admin(); check_admin_referer( 'formlyx_connect' ); $entry = isset( $_POST['formlyx_entry'] ) ? sanitize_key( wp_unslash( (string) $_POST['formlyx_entry'] ) ) : 'authorize'; $entry = 'signup' === $entry ? 'signup' : 'authorize'; $start = Authorization::begin( get_current_user_id(), $entry ); if ( ! $start['ok'] ) { Redirect::away( self::settings_url( $start['notice'] ) ); } Redirect::away( $start['url'] ); } /** * Ask Formlyx to confirm the saved connection. * * @since 1.0.0 * * @return void */ public static function handle_check(): void { self::require_admin(); check_admin_referer( 'formlyx_check' ); $notice = ConnectionStatus::check(); if ( 'connected' === $notice ) { $notice = 'checked'; } Redirect::away( self::settings_url( $notice ) ); } /** * Disconnect this site and attempt revocation. * * @since 1.0.0 * * @return void */ public static function handle_disconnect(): void { self::require_admin(); check_admin_referer( 'formlyx_disconnect' ); $result = TokenManager::revoke(); TokenManager::clear_tokens(); $notice = $result['confirmed'] ? 'disconnected' : 'disconnect_unconfirmed'; if ( ! $result['reachable'] ) { $notice = 'disconnect_unconfirmed'; } Redirect::away( self::settings_url( $notice ) ); } /** * Settings page URL, optionally with a notice code. * * @since 1.0.0 * * @param string $notice Notice code. * @return string */ public static function settings_url( string $notice = '' ): string { $url = admin_url( 'options-general.php?page=formlyx' ); if ( '' === $notice ) { return $url; } return add_query_arg( 'formlyx_notice', $notice, $url ); } /** * Stop when the current user cannot manage options. * * @since 1.0.0 * * @return void */ public static function require_admin(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Sorry, you are not allowed to manage Formlyx.', 'formlyx-forms' ), '', array( 'response' => 403 ) ); } } /** * Visitor-facing text for a notice code. * * @since 1.0.0 * * @param string $code Notice code. * @return string */ public static function notice_text( string $code ): string { switch ( $code ) { case 'connected': return __( 'Your site is connected to Formlyx.', 'formlyx-forms' ); case 'checked': return __( 'The Formlyx connection is working.', 'formlyx-forms' ); case 'disconnected': return __( 'This site is disconnected, and Formlyx confirmed the access was removed.', 'formlyx-forms' ); case 'disconnect_unconfirmed': return __( 'This site is disconnected. Formlyx did not confirm that access was removed. If the connection still appears in your Formlyx account, remove it there.', 'formlyx-forms' ); case 'denied': return __( 'The connection was cancelled. Nothing was changed.', 'formlyx-forms' ); case 'expired_link': return __( 'That connection attempt expired. Start again.', 'formlyx-forms' ); case 'invalid_link': return __( 'That connection attempt is no longer valid. Start again.', 'formlyx-forms' ); case 'invalid_issuer': return __( 'The connection response did not come from Formlyx. Nothing was saved.', 'formlyx-forms' ); case 'https_required': return __( 'Connect from an HTTPS site. HTTP is only available on localhost.', 'formlyx-forms' ); case 'registration_failed': return __( 'Formlyx could not start the connection. Try again in a few minutes.', 'formlyx-forms' ); case 'missing_scope': return __( 'Formlyx did not allow this site to read forms. Connect again and allow access.', 'formlyx-forms' ); case 'expired': return __( 'Formlyx needs you to connect again. The previous approval is no longer valid.', 'formlyx-forms' ); case 'unreachable': return __( 'Formlyx could not be reached. Your connection is still saved.', 'formlyx-forms' ); case 'refresh_busy': return __( 'Formlyx is updating the connection. Try again in a moment.', 'formlyx-forms' ); case 'connect_failed': return __( 'Formlyx could not finish connecting. Try again.', 'formlyx-forms' ); default: return ''; } } /** * Print a notice when the code is known. * * @since 1.0.0 * * @param string $code Notice code. * @return void */ private static function render_notice( string $code ): void { $text = self::notice_text( $code ); if ( '' === $text ) { return; } $class = in_array( $code, array( 'connected', 'checked', 'disconnected' ), true ) ? 'notice-success' : 'notice-warning'; if ( in_array( $code, array( 'invalid_issuer', 'expired', 'connect_failed', 'registration_failed' ), true ) ) { $class = 'notice-error'; } echo '

' . esc_html( $text ) . '

'; } /** * Disconnected content. * * @since 1.0.0 * * @return void */ private static function render_disconnected(): void { echo '

' . esc_html__( 'Connect your site', 'formlyx-forms' ) . '

'; echo '

' . esc_html__( 'Connect your WordPress website to Formlyx to select and embed your published forms.', 'formlyx-forms' ) . '

'; echo '
'; wp_nonce_field( 'formlyx_connect' ); echo ''; echo '

'; echo ' '; echo ''; echo '

'; } /** * Connected content. * * @since 1.0.0 * * @param array $connection Connection record. * @return void */ private static function render_connected( array $connection ): void { echo '

' . esc_html__( 'Connected to Formlyx', 'formlyx-forms' ) . '

'; echo '

' . esc_html__( 'Connection status', 'formlyx-forms' ) . ': ' . esc_html( self::status_label( (string) $connection['status'] ) ) . '

'; if ( '' !== $connection['workspace_name'] ) { echo '

' . esc_html__( 'Workspace', 'formlyx-forms' ) . ': ' . esc_html( (string) $connection['workspace_name'] ) . '

'; } if ( '' !== $connection['workspace_email'] ) { echo '

' . esc_html__( 'Account email', 'formlyx-forms' ) . ': ' . esc_html( (string) $connection['workspace_email'] ) . '

'; } if ( (int) $connection['checked_at'] > 0 ) { echo '

' . esc_html( sprintf( /* translators: %s: date and time of the last successful check. */ __( 'Last successful connection check: %s', 'formlyx-forms' ), wp_date( 'Y-m-d H:i', (int) $connection['checked_at'] ) ) ) . '

'; } if ( 'expired' === $connection['status'] ) { echo '

' . esc_html( self::notice_text( 'expired' ) ) . '

'; } elseif ( 'unreachable' === $connection['status'] ) { echo '

' . esc_html( self::notice_text( 'unreachable' ) ) . '

'; } echo '
'; wp_nonce_field( 'formlyx_connect' ); echo ''; echo ''; echo ''; echo '
'; echo '
'; wp_nonce_field( 'formlyx_check' ); echo ''; echo ''; echo '
'; echo '
'; wp_nonce_field( 'formlyx_disconnect' ); echo ''; echo ''; echo '
'; } /** * Status label. * * @since 1.0.0 * * @param string $status Stored status. * @return string */ private static function status_label( string $status ): string { switch ( $status ) { case 'connected': return __( 'Connected', 'formlyx-forms' ); case 'unreachable': return __( 'Temporarily unreachable', 'formlyx-forms' ); case 'expired': return __( 'Needs reconnecting', 'formlyx-forms' ); default: return __( 'Not connected', 'formlyx-forms' ); } } }