mailer = $mailer; } /** * {@inheritDoc} */ public function id(): string { return 'email'; } /** * {@inheritDoc} */ public function label(): string { return function_exists( '__' ) ? __( 'Email', 'buildler' ) : 'Email'; } /** * {@inheritDoc} */ public function is_configured(): bool { return true; } /** * {@inheritDoc} * * @param NotificationTemplate $template Template. */ public function supports( NotificationTemplate $template ): bool { return 'email' === $template->channel(); } /** * {@inheritDoc} * * @param NotificationTemplate $template Template. * @param VariableBag $bag Bag. */ public function render( NotificationTemplate $template, VariableBag $bag ): RenderedMessage { $subject_src = (string) ( $template->subject() ?? '' ); $body_src = $this->themes->load_body( $template->key() ) ?? (string) ( $template->body() ?? '' ); $subject = $this->renderer->replace( $subject_src, $bag, EscapeFormat::Text ); $html = $this->renderer->replace( $body_src, $bag, EscapeFormat::Html ); $text = $this->html_to_text( $this->renderer->replace( $body_src, $bag, EscapeFormat::Text ) ); $message = new RenderedMessage( $subject, $html, $text, null ); if ( function_exists( 'apply_filters' ) ) { /** * Filter a rendered notification message. * * @param RenderedMessage $message Message. * @param NotificationTemplate $template Template. * * @since 0.1.0 */ $filtered = apply_filters( 'bookline/notification/rendered', $message, $template ); if ( $filtered instanceof RenderedMessage ) { return $filtered; } } return $message; } /** * {@inheritDoc} * * @param RenderedMessage $message Message. * @param Recipient $recipient Recipient. */ public function send( RenderedMessage $message, Recipient $recipient ): SendResult { $headers = [ 'Content-Type: text/html; charset=UTF-8', 'From: ' . $this->from_header(), ]; $mailer = $this->mailer; if ( null !== $mailer ) { $ok = (bool) $mailer( $recipient->address(), $message->subject(), $message->body_html(), $headers, [] ); return $ok ? SendResult::ok( 'test' ) : SendResult::fail( 'Mailer returned false.', true ); } if ( ! function_exists( 'wp_mail' ) ) { return SendResult::fail( 'wp_mail is unavailable.', false ); } $ok = wp_mail( $recipient->address(), $message->subject(), $message->body_html(), $headers ); if ( $ok ) { return SendResult::ok(); } return SendResult::fail( 'wp_mail returned false.', true ); } /** * From header using settings with site defaults. */ private function from_header(): string { $name = (string) $this->settings->get( 'notifications.from_name' ); $email = (string) $this->settings->get( 'notifications.from_email' ); if ( '' === $name && function_exists( 'get_bloginfo' ) ) { $name = (string) get_bloginfo( 'name' ); } if ( '' === $email && function_exists( 'get_option' ) ) { $email = (string) get_option( 'admin_email' ); } if ( '' === $name ) { $name = 'Buildler'; } if ( '' === $email ) { $email = 'noreply@example.com'; } return sprintf( '%s <%s>', $this->strip_header( $name ), $this->strip_header( $email ) ); } /** * Strip CR/LF from header values. * * @param string $value Value. */ private function strip_header( string $value ): string { return str_replace( [ "\r", "\n" ], '', $value ); } /** * Produce a plain-text alternative from HTML source after text-mode substitution. * * @param string $html HTML or near-HTML. */ private function html_to_text( string $html ): string { $text = preg_replace( '//i', "\n", $html ) ?? $html; $text = preg_replace( '/<\/p>/i', "\n\n", $text ) ?? $text; if ( function_exists( 'wp_strip_all_tags' ) ) { $text = wp_strip_all_tags( $text ); } else { $text = preg_replace( '/<[^>]+>/', '', $text ) ?? $text; } return trim( html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, 'UTF-8' ) ); } }