From 83f57709ed4078a2c7c941be69a92924967af356 Mon Sep 17 00:00:00 2001 From: Piotr Potrebka <piotr.potrebka@wpdesk.net> Date: Wed, 1 Feb 2023 11:50:43 +0100 Subject: [PATCH] feat: email abstract --- src/Abstracts/EmailAbstract.php | 23 ++++ src/Abstracts/EmailInterface.php | 10 ++ src/Mailer.php | 177 +++++++++---------------------- 3 files changed, 86 insertions(+), 124 deletions(-) diff --git a/src/Abstracts/EmailAbstract.php b/src/Abstracts/EmailAbstract.php index d0d8730..274c336 100644 --- a/src/Abstracts/EmailAbstract.php +++ b/src/Abstracts/EmailAbstract.php @@ -58,6 +58,20 @@ abstract class EmailAbstract implements EmailInterface { */ abstract public function get_id(): string; + /** + * @return string + */ + public function get_from(): string { + return ''; + } + + /** + * @return string + */ + public function get_from_name(): string { + return ''; + } + /** * @return bool */ @@ -274,5 +288,14 @@ abstract class EmailAbstract implements EmailInterface { return $this->content; } + /** + * @param string $string + * + * @return array|string|string[] + */ + protected function replace_placeholders( string $string ): string { + return (string) str_replace( array_keys( $this->placeholders ), array_values( $this->placeholders ), $string ); + } + } diff --git a/src/Abstracts/EmailInterface.php b/src/Abstracts/EmailInterface.php index c82a432..35e9469 100644 --- a/src/Abstracts/EmailInterface.php +++ b/src/Abstracts/EmailInterface.php @@ -11,6 +11,16 @@ interface EmailInterface { */ public function get_id(): string; + /** + * @return string + */ + public function get_from(): string; + + /** + * @return string + */ + public function get_from_name(): string; + /** * Is enable. * diff --git a/src/Mailer.php b/src/Mailer.php index cc1d146..f8b5e02 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -2,13 +2,14 @@ namespace WPDesk\Library\WPEmail; +use Exception; +use WP_Error; use WPDesk\Library\WPEmail\Abstracts\EmailInterface; use WPDesk\Library\WPEmail\Helpers\HTML; use WPDesk\View\Renderer\Renderer; use WPDesk\View\Renderer\SimplePhpRenderer; use WPDesk\View\Resolver\ChainResolver; use WPDesk\View\Resolver\DirResolver; -use WPDesk\View\Resolver\Resolver; class Mailer { @@ -17,52 +18,29 @@ class Mailer { */ private $emails = []; - /** - * @var string - */ - private $from; - - /** - * @var string - */ - private $from_name; - /** * @var Renderer */ private $renderer; /** - * @var array - */ - protected $placeholders = []; - - /** - * @param string $from - * @param string $from_name - * @param Resolver[] $dir_resolvers + * @param array $dirs */ public function __construct( - string $from = 'wordpress@wordpress.org', - string $from_name = 'WordPress', - array $dir_resolvers = [] + array $dirs = [] ) { - $this->from = $from; - $this->from_name = $from_name; - $this->set_renderer( $this->init_renderer( $dir_resolvers ) ); + $this->set_renderer( $this->init_renderer( $dirs ) ); } /** - * @param array $dir_resolvers + * @param array $dirs * * @return Renderer */ - private function init_renderer( array $dir_resolvers ): Renderer { + private function init_renderer( array $dirs = [] ): Renderer { $resolver = new ChainResolver(); - foreach ( $dir_resolvers as $dir_resolver ) { - if ( $dir_resolver instanceof Resolver ) { - $resolver->appendResolver( $dir_resolver ); - } + foreach ( $dirs as $dir ) { + $resolver->appendResolver( new DirResolver( $dir ) ); } $resolver->appendResolver( new DirResolver( __DIR__ ) ); @@ -94,99 +72,59 @@ class Mailer { return $this->emails; } - - /** - * Set placeholders. - * - * @param array $placeholders - * - * @return self - */ - public function set_placeholders( array $placeholders = [] ): self { - $this->placeholders = array_merge( $this->placeholders, $placeholders ); - - return $this; - } - - /** - * Get defined placeholders. - * - * @return string[] - */ - public function get_placeholders(): array { - return $this->placeholders; - } - - /** - * WordPress callback for setting the from email - * - * @param string $email - * - * @return string - */ - public function from_filter( string $email ): string { - if ( ! empty( $this->from ) && is_email( $this->from ) ) { - $email = $this->from; - } - - return $email; - } - - - /** - * WordPress callback for setting the from name - * - * @param string $name - * - * @return string - */ - public function from_name_filter( string $name ): string { - if ( ! empty( $this->from_name ) ) { - $name = html_entity_decode( sanitize_text_field( $this->from_name ) ); - } - - return $name; - } - - /** - * Add filters before fire wp_mail. - * - * @return void - */ - protected function before_wp_mail() { - add_filter( 'wp_mail_from', array( $this, 'from_filter' ) ); - add_filter( 'wp_mail_from_name', array( $this, 'from_name_filter' ) ); - } - + /** @return void */ public function send() { - $this->before_wp_mail(); foreach ( $this->get_emails() as $email ) { - $subject = $this->replace_placeholders( $email->get_subject() ); - if ( $email->get_is_enable() ) { - wp_mail( - $email->get_recipients(), $subject, $this->get_body( $email ), $email->get_headers(), $email->get_attachments() + add_filter( + 'wp_mail_from', + $from_cb = static function () use ( $email ) { + return $email->get_from(); + } + ); + add_filter( + 'wp_mail_from_name', + $from_name_cb = static function () use ( $email ) { + return $email->get_from_name(); + } + ); + add_action( 'wp_mail_failed', [ $this, 'catch_error' ] ); + + try { + $success = wp_mail( + $email->get_recipients(), + $email->get_subject(), + $this->get_email_template( $email ), + $email->get_headers(), + $email->get_attachments() ); + if ( ! $success ) { + throw new MailerException( 'Count not send the mail with wp_mail()' ); + } + } catch ( Exception $e ) { + if ( $e instanceof MailerException ) { + throw $e; + } + + throw new MailerException( sprintf( 'wp_mail() failure. Original error: %s', $e->getMessage() ), 0, $e ); + } finally { + remove_action( 'wp_mail_failed', [ $this, 'catch_error' ], 99999 ); + remove_filter( 'wp_mail_from', $from_cb ); + remove_filter( 'wp_mail_from_name', $from_name_cb ); } } - $this->after_wp_mail(); } - protected function get_body( EmailInterface $email ): string { - $content = $this->replace_placeholders( $email->get_content() ); - $output = $this->renderer->render( 'html/email-header', [ 'heading' => $email->get_heading(), 'logo' => '' ] ); - $output .= $this->renderer->render( 'html/' . $email->get_id(), [ 'content' => $content ] ); - $output .= $this->renderer->render( 'html/email-footer', [ 'footer' => '' ] ); - - return $this->css_inline( $output ); + /** @return void */ + public function catch_error( WP_Error $error ) { + throw MailerException::with_wp_error( $error ); } - /** - * @param string $string - * - * @return array|string|string[] - */ - protected function replace_placeholders( string $string ): string { - return (string) str_replace( array_keys( $this->placeholders ), array_values( $this->placeholders ), $string ); + protected function get_email_template( EmailInterface $email ): string { + $output = $this->renderer->render( 'html/email-header', [ 'heading' => $email->get_heading(), 'logo' => '' ] ); + $output .= $this->renderer->render( 'html/' . $email->get_id(), [ 'content' => $email->get_content() ] ); + $output .= $this->renderer->render( 'html/email-footer', [ 'footer' => '' ] ); + + return $this->css_inline( $output ); } /** @@ -200,14 +138,5 @@ class Mailer { return HTML::style_inline( $content, $styles ); } - /** - * Remove filters after fire wp_mail. - * - * @return void - */ - protected function after_wp_mail() { - remove_filter( 'wp_mail_from', array( $this, 'from_filter' ) ); - remove_filter( 'wp_mail_from_name', array( $this, 'from_name_filter' ) ); - } } -- GitLab