<?php 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; class Mailer { /** * @var EmailInterface[] */ private $emails = []; /** * @var Renderer */ private $renderer; /** * @param array $dirs */ public function __construct( array $dirs = [] ) { $this->set_renderer( $this->init_renderer( $dirs ) ); } /** * @param array $dirs * * @return Renderer */ private function init_renderer( array $dirs = [] ): Renderer { $resolver = new ChainResolver(); foreach ( $dirs as $dir ) { $resolver->appendResolver( new DirResolver( $dir ) ); } $resolver->appendResolver( new DirResolver( __DIR__ . '/templates' ) ); return new SimplePhpRenderer( $resolver ); } /** * @param Renderer $renderer * * @return void */ public function set_renderer( Renderer $renderer ) { $this->renderer = $renderer; } /** * @param EmailInterface $email * * @return void */ public function add_email( EmailInterface $email ) { $this->emails[ $email->get_id() ] = $email; } /** * @return EmailInterface[] */ public function get_emails(): array { return $this->emails; } /** @return void */ public function send() { foreach ( $this->get_emails() as $email ) { 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 ); } } } /** @return void */ public function catch_error( WP_Error $error ) { throw MailerException::with_wp_error( $error ); } 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 ); } /** * @param string $content * * @return mixed|string */ protected function css_inline( string $content ): string { $styles = $this->renderer->render( 'html/email-styles', [] ); return HTML::style_inline( $content, $styles ); } }