display_name : __( 'Former team member', 'accessible-forms-by-accessible-org' ); } /** * Readable label for a recorded activity. * * @param string $action Stored action name. * @return string */ public static function activity_label( $action ) { $labels = array( 'entry_read' => __( 'Marked as read', 'accessible-forms-by-accessible-org' ), 'entry_updated' => __( 'Updated follow-up', 'accessible-forms-by-accessible-org' ), 'entry_workflow' => __( 'Saved follow-up', 'accessible-forms-by-accessible-org' ), 'entry_unread' => __( 'Marked as unread', 'accessible-forms-by-accessible-org' ), 'entry_spam' => __( 'Marked as spam', 'accessible-forms-by-accessible-org' ), 'entry_ham' => __( 'Accepted without sending email', 'accessible-forms-by-accessible-org' ), 'entry_accept_notify' => __( 'Accepted and notified recipients', 'accessible-forms-by-accessible-org' ), 'entry_resend' => __( 'Queued the notification again', 'accessible-forms-by-accessible-org' ), 'entry_trash' => __( 'Moved to Trash', 'accessible-forms-by-accessible-org' ), 'entry_restore' => __( 'Restored from Trash', 'accessible-forms-by-accessible-org' ), 'entry_reply' => __( 'Replied to the visitor', 'accessible-forms-by-accessible-org' ), 'entry_reply_test' => __( 'Sent a test reply', 'accessible-forms-by-accessible-org' ), 'entry_reply_failed' => __( 'Reply could not be sent', 'accessible-forms-by-accessible-org' ), 'entry_reply_unrecorded' => __( 'Reply sent but not saved in notes', 'accessible-forms-by-accessible-org' ), 'bulk_read' => __( 'Marked as read (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_unread' => __( 'Marked as unread (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_spam' => __( 'Marked as spam (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_ham' => __( 'Accepted without notifying (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_trash' => __( 'Moved to Trash (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_delete' => __( 'Deleted permanently (bulk)', 'accessible-forms-by-accessible-org' ), 'bulk_resend' => __( 'Asked to send the notification again (bulk)', 'accessible-forms-by-accessible-org' ), 'resend_original_recipients' => __( 'Notification queued again for the original recipients', 'accessible-forms-by-accessible-org' ), 'resend_current_recipients' => __( 'Notification queued again for the current recipients', 'accessible-forms-by-accessible-org' ), 'attachment_approved' => __( 'Approved an attachment', 'accessible-forms-by-accessible-org' ), 'attachment_downloaded' => __( 'Downloaded an attachment', 'accessible-forms-by-accessible-org' ), 'attachment_downloaded_for_review' => __( 'Downloaded an attachment for review', 'accessible-forms-by-accessible-org' ), 'form_exported' => __( 'Exported the form', 'accessible-forms-by-accessible-org' ), 'form_exported_recipients' => __( 'Exported the form with its recipients', 'accessible-forms-by-accessible-org' ), 'form_imported' => __( 'Imported the form as a draft', 'accessible-forms-by-accessible-org' ), 'form_import_updated' => __( 'Updated the form from an import', 'accessible-forms-by-accessible-org' ), 'entries_imported' => __( 'Imported entries from a file', 'accessible-forms-by-accessible-org' ), 'settings_exported' => __( 'Exported settings', 'accessible-forms-by-accessible-org' ), 'settings_imported' => __( 'Imported settings', 'accessible-forms-by-accessible-org' ), ); return $labels[ $action ] ?? ucfirst( str_replace( '_', ' ', (string) $action ) ); } /** * Readable label for a notification job or attempt status. * * @param string $status Stored status. * @return string */ /** * Where a notification went: its recipients, or the host of an add-on's destination. * * @param array $config Notification. * @return string */ private static function destination( array $config ) { if ( isset( $config['destination'] ) && is_string( $config['destination'] ) ) { return $config['destination']; } if ( 'email' !== Notifications::channel( $config ) ) { return (string) wp_parse_url( (string) ( $config['url'] ?? '' ), PHP_URL_HOST ); } return implode( ', ', (array) ( $config['recipients'] ?? array() ) ); } private static function status_label( $status ) { $labels = array( 'pending' => __( 'Waiting to send', 'accessible-forms-by-accessible-org' ), 'sending' => __( 'Sending', 'accessible-forms-by-accessible-org' ), 'accepted' => __( 'Accepted', 'accessible-forms-by-accessible-org' ), 'failed' => __( 'Failed', 'accessible-forms-by-accessible-org' ), 'uncertain' => __( 'Delivery uncertain', 'accessible-forms-by-accessible-org' ), 'cancelled' => __( 'Cancelled', 'accessible-forms-by-accessible-org' ), ); return $labels[ $status ] ?? (string) $status; } /** * One attempt in the notification history, with the reason explained. * * @param array $attempt Stored attempt. */ private static function attempt( array $attempt ) { echo '
  • ' . esc_html( self::local_time( $attempt['at'] ?? '' ) . ' · ' . self::status_label( $attempt['status'] ?? '' ) ); if ( ! empty( $attempt['code'] ) ) { echo ' ' . esc_html( sprintf( /* translators: %d: HTTP status code. */ __( '(HTTP %d)', 'accessible-forms-by-accessible-org' ), $attempt['code'] ) ); } self::mail_routes( $attempt['routes'] ?? array() ); if ( ! empty( $attempt['reason'] ) ) { $explained = Notifications::explain( $attempt['reason'] ); echo '
    ' . esc_html( $explained['summary'] ) . ' ' . esc_html( $explained['next'] ) . ''; if ( ! empty( $attempt['detail'] ) ) { echo '
    ' . esc_html( sprintf( /* translators: %s: technical error message. */ __( 'Technical detail: %s', 'accessible-forms-by-accessible-org' ), $attempt['detail'] ) ) . ''; } } echo '
  • '; } /** The route and outcome of each handoff, without exposing message content. */ public static function mail_routes( array $routes ) { foreach ( array_slice( $routes, 0, 2 ) as $route ) { echo '

    ' . esc_html( sprintf( /* translators: 1: mail transport, 2: handoff status. */ __( 'Mail route: %1$s: %2$s', 'accessible-forms-by-accessible-org' ), $route['transport'] ?? '', self::status_label( $route['status'] ?? '' ) ) ) . '

    '; if ( ! empty( $route['reference'] ) ) { echo '

    ' . esc_html( sprintf( /* translators: %s: SMTP provider queue reference. */ __( 'Provider reference: %s', 'accessible-forms-by-accessible-org' ), $route['reference'] ) ) . '

    '; } if ( ! empty( $route['reason'] ) ) { $explained = Notifications::explain( $route['reason'] ); echo '

    ' . esc_html( $explained['summary'] ) . ( 'uncertain' === ( $route['status'] ?? '' ) ? ' ' . esc_html( $explained['next'] ) : '' ) . '

    '; } } } public static function start( $entry ) { echo '
    '; static $nonce_number = 0; ++$nonce_number; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WordPress escapes this nonce markup; only a fixed-prefix ID changes. echo str_replace( 'id="_wpnonce"', 'id="af-entry-nonce-' . $nonce_number . '"', wp_nonce_field( EntryView::NONCE, '_wpnonce', false, false ) ); EntryView::view_field(); } public static function render( array $entry ) { // Add-ons add cards first, such as a reply form and follow-up. Extensions::notify( 'accessible_forms_entry_cards', $entry ); echo '

    ' . esc_html__( 'Notification history', 'accessible-forms-by-accessible-org' ) . '

    ' . esc_html__( 'Accepted means the mail service accepted the request. It does not confirm inbox delivery. An uncertain attempt is held for manual review.', 'accessible-forms-by-accessible-org' ) . '

    '; $jobs = Notifications::history( $entry['id'] ); if ( ! $jobs ) { echo '

    ' . esc_html__( 'No queued notification attempts are recorded.', 'accessible-forms-by-accessible-org' ) . '

    '; } else { echo ''; foreach ( $jobs as $job ) { $config = json_decode( $job['config'], true ) ?: array(); echo ''; } echo '
    ' . esc_html__( 'Notification', 'accessible-forms-by-accessible-org' ) . '' . esc_html__( 'Recipients / destination', 'accessible-forms-by-accessible-org' ) . '' . esc_html__( 'Status', 'accessible-forms-by-accessible-org' ) . '
    ' . esc_html( $config['name'] ?? '' ) . '' . esc_html( self::destination( $config ) ) . '' . esc_html( self::status_label( $job['status'] ) ) . '
      '; foreach ( json_decode( (string) $job['history'], true ) ?: array() as $attempt ) { if ( is_array( $attempt ) ) { self::attempt( $attempt ); } } echo '
    '; } if ( Capabilities::entry( $entry, 'send_accessible_form_notifications' ) && 'received' === $entry['status'] ) { self::start( $entry ); Editor::select( 'use_current', __( 'Recipient configuration for this resend', 'accessible-forms-by-accessible-org' ), array( '0' => __( 'Original recipients saved with this entry', 'accessible-forms-by-accessible-org' ), '1' => __( 'Current published form recipients', 'accessible-forms-by-accessible-org' ), ), '0' ); echo '

    ' . esc_html__( 'This deliberately sends another copy. Check the attempt history first.', 'accessible-forms-by-accessible-org' ) . '

    '; } echo '
    '; $activity = Audit::recent( $entry['id'] ); if ( $activity ) { echo '
    ' . esc_html__( 'Activity', 'accessible-forms-by-accessible-org' ) . '
    '; } } }