diff --git a/composer.json b/composer.json index 193f1c953a0e4950f3a15268957e772c20ee9513..672f320aa37e59bdd196d713529ff9fb25ce8e1a 100644 --- a/composer.json +++ b/composer.json @@ -41,16 +41,18 @@ "require-dev": { "10up/wp_mock": "*", "mockery/mockery": "*", - "phpunit/phpunit": "<7", - "wp-coding-standards/wpcs": "^2.3.0", - "squizlabs/php_codesniffer": "^3.0.2" + "phpunit/phpunit": "<7" }, "autoload": { "psr-4": { "WPDesk\\Library\\WPEmail\\": "src" } }, - "autoload-dev": {}, + "autoload-dev": { + "psr-4": { + "Tests\\Mailer\\": "tests/unit" + } + }, "extra": { "text-domain": "wp-email", "translations-folder": "lang", diff --git a/phpunit-unit.xml b/phpunit-unit.xml index f3b7ead97601294e87575236952d21711e0cec07..74290fab09e79ac5a90ecbef0fb675d363c99992 100644 --- a/phpunit-unit.xml +++ b/phpunit-unit.xml @@ -1,21 +1,17 @@ <phpunit bootstrap="tests/unit/bootstrap.php"> <testsuites> - <testsuite> - <directory prefix="Test_" suffix=".php">./tests/unit/</directory> + <testsuite name="unit"> + <directory suffix="Test.php">./tests/unit/</directory> </testsuite> </testsuites> <filter> <whitelist> <directory suffix=".php">src</directory> + <exclude> + <directory suffix=".php">src/templates</directory> + </exclude> </whitelist> </filter> - <logging> - <log type="junit" target="build-coverage/report.junit.xml"/> - <log type="coverage-html" target="build-coverage/coverage" charset="UTF-8" yui="true" highlight="true"/> - <log type="coverage-text" target="build-coverage/coverage.txt"/> - <log type="coverage-clover" target="build-coverage/clover.xml"/> - </logging> - </phpunit> diff --git a/src/Abstracts/ConditionInterface.php b/src/Abstracts/ConditionInterface.php deleted file mode 100644 index 94bc2569919fd1e363d3062fc17a5eabe7f96711..0000000000000000000000000000000000000000 --- a/src/Abstracts/ConditionInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -namespace WPDesk\Library\WPEmail\Abstracts; - -use WPDesk\View\Renderer\Renderer; - -interface ConditionInterface { - - public function is_valid(): bool; - -} diff --git a/src/Abstracts/Email.php b/src/Abstracts/Email.php new file mode 100644 index 0000000000000000000000000000000000000000..d21f2bb7ec8f7d3bc2af47af6a784e82d8444959 --- /dev/null +++ b/src/Abstracts/Email.php @@ -0,0 +1,213 @@ +<?php + +namespace WPDesk\Library\WPEmail\Abstracts; + +use Exception; + +class Email { + + /** + * @var array + */ + private $recipients = []; + + /** + * @var string + */ + private $subject = ''; + + /** + * @var array + */ + private $attachments = []; + + /** + * @var string + */ + private $content = ''; + + /** + * @var array + */ + private $headers = [ 'Content-Type' => 'text/html' ]; + + /** + * @var string + */ + private $from_email; + + /** + * @var string + */ + private $from_name; + + /** + * @var array + */ + private $template_attributes; + + /** + * @param string $from_email + * + * @return self + */ + public function set_from( string $from_email ): self { + $this->from_email = $from_email; + + return $this; + } + + /** + * @return string + */ + public function get_from(): string { + return $this->from_email; + } + + /** + * @param string $from_name + * + * @return self + */ + public function set_from_name( string $from_name ): self { + $this->from_name = $from_name; + + return $this; + } + + /** + * @return string + */ + public function get_from_name(): string { + return wp_specialchars_decode( esc_html( $this->from_name ), ENT_QUOTES ); + } + + /** + * @param string $subject + * + * @return self + */ + public function set_subject( string $subject ): self { + $this->subject = $subject; + + return $this; + } + + /** + * @return string + * @throws Exception + */ + public function get_subject(): string { + return $this->subject; + } + + /** + * @param array $recipients + * + * @return self + */ + public function set_recipients( array $recipients = [] ): self { + $this->recipients = $recipients; + + return $this; + } + + /** + * @return string[] + */ + public function get_recipients(): array { + return $this->recipients; + } + + public function set_header( string $header, string $value ): self { + $this->headers[ $header ] = $value; + + return $this; + } + + /** @return string[] */ + public function get_headers(): array { + $result = []; + foreach ( $this->headers as $header => $value ) { + $result[] = "$header: $value"; + } + + return $result; + } + + public function get_header( string $header ): string { + return $this->headers[ $header ] ?? ''; + } + + /** + * @param array $attachments + * + * @return self + */ + public function set_attachments( array $attachments ): self { + $this->attachments = $attachments; + + return $this; + } + + /** + * @return array + */ + public function get_attachments(): array { + return $this->attachments; + } + + public function is_html(): bool { + return $this->get_header( 'Content-Type' ) === 'text/html'; + } + + /** + * @return string + */ + public function set_content_type( $type = 'html' ): self { + switch ( $type ) { + case 'plain': + $content_type = 'text/plain'; + break; + case 'multipart': + $content_type = 'multipart/alternative'; + break; + default: + $content_type = 'text/html'; + } + + $this->set_header( 'Content-Type', $content_type ); + + return $this; + } + + /** + * @param string $content + * + * @return self + */ + public function set_content( string $content ): self { + $this->content = $content; + + return $this; + } + + /** + * @return string + * @throws Exception + */ + public function get_content(): string { + return $this->content; + } + + public function set_template_attributes( string $name, string $value ): self { + $this->template_attributes[ $name ] = $value; + + return $this; + } + + public function get_template_attributes(): array { + return $this->template_attributes; + } + +} diff --git a/src/Abstracts/EmailAbstract.php b/src/Abstracts/EmailAbstract.php deleted file mode 100644 index 2e326eadfb8ab503ee18bfb08203ef69cc4fa99c..0000000000000000000000000000000000000000 --- a/src/Abstracts/EmailAbstract.php +++ /dev/null @@ -1,306 +0,0 @@ -<?php - -namespace WPDesk\Library\WPEmail\Abstracts; - -use Exception; - -abstract class EmailAbstract implements EmailInterface { - - /** - * @var bool - */ - private $is_enable; - - /** - * @var array - */ - private $recipients = []; - - /** - * @var array - */ - private $placeholders = []; - - /** - * @var string - */ - private $subject = ''; - - /** - * @var string - */ - private $heading = ''; - - /** - * @var array - */ - private $attachments = []; - - /** - * @var string - */ - private $content = ''; - - /** - * @var string - */ - private $type = 'html'; - - /** - * @var array - */ - private $headers = [ 'Content-Type: text/html; charset=UTF-8' ]; - - /** - * @var string - */ - private $from_email; - - /** - * @var string - */ - private $from_name; - - /** - * @return string - */ - abstract public function get_id(): string; - - /** - * @return string - */ - public function get_template_name(): string { - return 'default'; - } - - /** - * @return string - */ - public function get_from(): string { - return sanitize_email( $this->from_email ); - } - - /** - * @param string $from_email - * - * @return self - */ - public function set_from( string $from_email ): self { - $this->from_email = $from_email; - - return $this; - } - - /** - * @param string $from_name - * - * @return self - */ - public function set_from_name( string $from_name ): self { - $this->from_name = $from_name; - - return $this; - } - - /** - * @return string - */ - public function get_from_name(): string { - return wp_specialchars_decode( esc_html( $this->from_name ), ENT_QUOTES ); - } - - /** - * @return bool - */ - public function get_is_enable(): bool { - return $this->is_enable; - } - - /** - * @param $enable - * - * @return EmailAbstract - */ - public function set_is_enable( $enable ): self { - $this->is_enable = $enable; - - return $this; - } - - /** - * @param array $placeholders - * - * @return self - */ - public function set_placeholders( array $placeholders = [] ): self { - $this->placeholders = array_merge( $this->placeholders, $placeholders ); - - return $this; - } - - /** - * @return string[] - */ - public function get_placeholders(): array { - return $this->placeholders; - } - - /** - * @param string $subject - * - * @return self - */ - public function set_subject( string $subject ): self { - $this->subject = $subject; - - return $this; - } - - /** - * @return string - * @throws Exception - */ - public function get_subject(): string { - if ( ! $this->subject ) { - throw new Exception( 'Empty email subject' ); - } - - return $this->replace_placeholders( $this->subject ); - } - - /** - * @param string $heading - * - * @return self - */ - public function set_heading( string $heading ): self { - $this->heading = $heading; - - return $this; - } - - /** - * @return string - */ - public function get_heading(): string { - return $this->replace_placeholders( $this->heading ); - } - - /** - * @param array $recipients - * - * @return self - */ - public function set_recipients( array $recipients = [] ): self { - $this->recipients = $recipients; - - return $this; - } - - /** - * @return string[] - */ - public function get_recipients(): array { - return $this->recipients; - } - - /** - * @param array $headers - * - * @return self - */ - public function set_headers( array $headers = [] ): self { - $this->headers = $headers; - - return $this; - } - - /** - * @return string[] - */ - public function get_headers(): array { - return $this->headers; - } - - /** - * @param array $attachments - * - * @return self - */ - public function set_attachments( array $attachments ): self { - $this->attachments = $attachments; - - return $this; - } - - /** - * @return array - */ - public function get_attachments(): array { - return $this->attachments; - } - - /** - * @param string $type - * - * @return self - */ - public function set_type( string $type = 'html' ): self { - $this->type = $type; - - return $this; - } - - /** - * @return string - */ - public function get_type(): string { - return $this->type; - } - - /** - * @return string - */ - public function get_content_type(): string { - switch ( $this->get_type() ) { - case 'html': - return 'text/html'; - case 'multipart': - return 'multipart/alternative'; - default: - return 'text/plain'; - } - } - - /** - * @param string $content - * - * @return self - */ - public function set_content( string $content ): self { - $this->content = $content; - - return $this; - } - - /** - * @return string - * @throws Exception - */ - public function get_content(): string { - return $this->replace_placeholders( $this->content ); - } - - /** - * @return array|string|string[] - */ - protected function replace_placeholders( string $string ): string { - if ( empty( $this->placeholders ) ) { - return $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 deleted file mode 100644 index 61a4ea8a251125fdfef9659567cb7696648a24ac..0000000000000000000000000000000000000000 --- a/src/Abstracts/EmailInterface.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php - -namespace WPDesk\Library\WPEmail\Abstracts; - -interface EmailInterface { - - /** - * Define unique email ID. - * - * @return string - */ - public function get_id(): string; - - /** - * Get template name. - * - * @return string - */ - public function get_template_name(): string; - - /** - * @return string - */ - public function get_from(): string; - - /** - * @return string - */ - public function get_from_name(): string; - - /** - * Is enable. - * - * @return bool - */ - public function get_is_enable(): bool; - - /** - * Get defined placeholders. - * - * @return array - */ - public function get_placeholders(): array; - - /** - * Get email subject. - * - * @return string - */ - public function get_subject(): string; - - /** - * Get email heading. - * - * @return string - */ - public function get_heading(): string; - - /** - * Get valid recipients. - * - * @return string[] - */ - public function get_recipients(): array; - - /** - * Get email headers. - * - * @return string[] - */ - public function get_headers(): array; - - /** - * Get email attachments. - * - * @return array - */ - public function get_attachments(): array; - - /** - * Get email type. - * - * @return string - */ - public function get_type(): string; - - /** - * Get content type. - * - * @return string - */ - public function get_content_type(): string; - - /** - * Get email content. - * - * @return string - */ - public function get_content(): string; - -} diff --git a/src/Abstracts/Mailer.php b/src/Abstracts/Mailer.php new file mode 100644 index 0000000000000000000000000000000000000000..0602ff20db09f65bf87632c259a677d28c75a367 --- /dev/null +++ b/src/Abstracts/Mailer.php @@ -0,0 +1,15 @@ +<?php + +namespace WPDesk\Library\WPEmail\Abstracts; + +use WPDesk\Library\WPEmail\Exceptions\MailerException; + +interface Mailer { + + /** + * @throws MailerException + */ + public function send( Email $email ): void; + +} + diff --git a/src/MailerException.php b/src/Exceptions/MailerException.php similarity index 88% rename from src/MailerException.php rename to src/Exceptions/MailerException.php index 9dd31547c57459530437bcfe38f7bc95c2201255..6c005cd4975cdb253742004f5b71ce244db0c1b5 100644 --- a/src/MailerException.php +++ b/src/Exceptions/MailerException.php @@ -2,7 +2,7 @@ declare( strict_types=1 ); -namespace WPDesk\Library\WPEmail; +namespace WPDesk\Library\WPEmail\Exceptions; class MailerException extends \RuntimeException { diff --git a/src/Helpers/Template.php b/src/Helpers/ColorConversion.php similarity index 99% rename from src/Helpers/Template.php rename to src/Helpers/ColorConversion.php index 0096d9d3824df52ef1c611caf92088d20918fc22..e8242ee402eaa058e124241c4dbda8d4a13337d5 100644 --- a/src/Helpers/Template.php +++ b/src/Helpers/ColorConversion.php @@ -2,7 +2,7 @@ namespace WPDesk\Library\WPEmail\Helpers; -class Template { +class ColorConversion { /** * Determine whether a hex color is light. diff --git a/src/Helpers/HTML.php b/src/Helpers/StyleInliner.php similarity index 63% rename from src/Helpers/HTML.php rename to src/Helpers/StyleInliner.php index aace0afe080492ebe87a68601ae58f6d332b4c80..9068deeddfad4b16d4da360d196d05c1035b2ae7 100644 --- a/src/Helpers/HTML.php +++ b/src/Helpers/StyleInliner.php @@ -6,9 +6,9 @@ use Pelago\Emogrifier\CssInliner; use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter; use Pelago\Emogrifier\HtmlProcessor\HtmlPruner; -class HTML { +class StyleInliner { - public static function style_inline( $content, $styles = '' ) { + public static function inline( string $content, string $styles = '' ): string { if ( class_exists( 'DOMDocument' ) ) { try { $css_inliner = CssInliner::fromHtml( $content )->inlineCss( $styles ); @@ -21,10 +21,21 @@ class HTML { error_log( $e->getMessage() ); } } else { - $content = '<style type="text/css">' . strip_tags( $styles ) . '</style>' . $content; + $content = '<style>' . strip_tags( $styles ) . '</style>' . $content; } return $content; } + /** + * @return array|string|string[] + */ + protected function replace_placeholders( string $string ): string { + if ( empty( $this->placeholders ) ) { + return $string; + } + + return (string) str_replace( array_keys( $this->placeholders ), array_values( $this->placeholders ), $string ); + } + } diff --git a/src/Mailer.php b/src/Mailer.php deleted file mode 100644 index be4ce751772fbfd2040a7c5148c2b53768860779..0000000000000000000000000000000000000000 --- a/src/Mailer.php +++ /dev/null @@ -1,216 +0,0 @@ -<?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; - - /** - * @var array - */ - private $template_attributes; - - /** - * @var string - */ - private $from; - - /** - * @var string - */ - private $from_name; - - /** - * @param array $dirs - * @param array $template_attributes - */ - public function __construct( - array $dirs = [], - array $template_attributes = [] - ) { - $this->template_attributes = $template_attributes; - $this->set_renderer( $this->init_renderer( $dirs ) ); - $this->set_from( get_bloginfo( 'admin_email' ) ); - $this->set_from_name( get_bloginfo( 'name', 'display' ) ); - } - - /** - * @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( dirname( __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; - } - - /** - * @param string $from - * - * @return void - */ - public function set_from( string $from ) { - $this->from = $from; - } - - /** - * @return string - */ - public function get_from(): string { - return $this->from; - } - - /** - * @param string $from_name - * - * @return void - */ - public function set_from_name( string $from_name ) { - $this->from_name = $from_name; - } - - /** - * @return string - */ - public function get_from_name(): string { - return $this->from_name; - } - - /** @return void */ - public function send( $include = [] ) { - foreach ( $this->get_emails() as $email ) { - if ( ! empty( $include ) && ! in_array( $email->get_id(), $include, true ) ) { - continue; - } - if ( $email->get_is_enable() ) { - $mailer_from = $this->get_from(); - add_filter( - 'wp_mail_from', - $from_cb = static function ( $from ) use ( $mailer_from ) { - return $mailer_from; - } - ); - - $mailer_from_name = $this->get_from_name(); - add_filter( - 'wp_mail_from_name', - $from_name_cb = static function ( $from_name ) use ( $mailer_from_name ) { - return $mailer_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' => $this->template_attributes['heading'] ?? $email->get_heading(), - 'logo' => $this->template_attributes['logo'] - ] - ); - $output .= $this->renderer->render( 'html/' . $email->get_id(), [ 'content' => $email->get_content() ] ); - $output .= $this->renderer->render( 'html/email-footer', [ 'footer' => $this->template_attributes['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', - [ - 'primary' => $this->template_attributes['primary'] ?? '#d15291', - 'text' => $this->template_attributes['text'] ?? '#303030', - 'bg' => $this->template_attributes['bg'] ?? '#f9f9f9', - 'body' => $this->template_attributes['body'] ?? '#ffffff', - ] - ); - - return HTML::style_inline( $content, $styles ); - } - -} diff --git a/src/Template.php b/src/Template.php new file mode 100644 index 0000000000000000000000000000000000000000..c0c66bac330d0f71b66e69ed4a8d03f94b97eab2 --- /dev/null +++ b/src/Template.php @@ -0,0 +1,56 @@ +<?php + +namespace WPDesk\Library\WPEmail; + +use WPDesk\Library\WPEmail\Helpers\StyleInliner; +use WPDesk\View\Renderer\Renderer; + +class Template { + + /** + * @var Renderer + */ + private $renderer; + + /** + * @var array + */ + private $template_attributes; + + public function __construct( Renderer $renderer, array $template_attributes ) { + $this->renderer = $renderer; + $this->template_attributes = wp_parse_args( $template_attributes, $this->get_default_template_attributes() ); + } + + public function get_body( string $content ): string { + $output = $this->renderer->render( 'html/email-header', $this->template_attributes ); + $output .= $this->renderer->render( 'html/email-content', [ 'content' => $content ] ); + $output .= $this->renderer->render( 'html/email-footer', [ 'footer' => $this->template_attributes['footer'] ] ); + + return $this->css_inline( $output ); + } + + /** + * @param string $content + * + * @return mixed|string + */ + public function css_inline( string $content ): string { + $styles = $this->renderer->render( 'html/email-styles', $this->template_attributes ); + + return StyleInliner::inline( $content, $styles ); + } + + public function get_default_template_attributes(): array { + return [ + 'heading' => '', + 'logo' => '', + 'footer' => '', + 'primary' => '#d15291', + 'text' => '#303030', + 'bg' => '#f9f9f9', + 'body' => '#ffffff', + ]; + } + +} diff --git a/src/WPMailer.php b/src/WPMailer.php new file mode 100644 index 0000000000000000000000000000000000000000..9097fc757c20f9c4be16808d4d7d382b49a21ae1 --- /dev/null +++ b/src/WPMailer.php @@ -0,0 +1,87 @@ +<?php + +namespace WPDesk\Library\WPEmail; + +use Exception; +use WP_Error; +use WPDesk\Library\WPEmail\Abstracts\Email; +use WPDesk\Library\WPEmail\Abstracts\Mailer; +use WPDesk\Library\WPEmail\Exceptions\MailerException; +use WPDesk\View\Renderer\Renderer; +use WPDesk\View\Renderer\SimplePhpRenderer; +use WPDesk\View\Resolver\ChainResolver; +use WPDesk\View\Resolver\DirResolver; + +class WPMailer implements Mailer { + + /** + * @var Renderer + */ + private $renderer; + + public function __construct() { + $resolver = new ChainResolver(); + $resolver->appendResolver( new DirResolver( __DIR__ . '/templates' ) ); + $renderer = new SimplePhpRenderer( $resolver ); + $this->set_renderer( $renderer ); + } + + public function set_renderer( Renderer $renderer ) { + $this->renderer = $renderer; + } + + public function get_renderer(): Renderer { + return $this->renderer; + } + + /** @return void */ + public function send( Email $email ): void { + $mailer_from = $email->get_from(); + add_filter( + 'wp_mail_from', + $from_cb = static function ( $from ) use ( $mailer_from ) { + return $mailer_from; + } + ); + + $mailer_from_name = $email->get_from_name(); + add_filter( + 'wp_mail_from_name', + $from_name_cb = static function ( $from_name ) use ( $mailer_from_name ) { + return $mailer_from_name; + } + ); + add_action( 'wp_mail_failed', [ $this, 'catch_error' ] ); + + $email_template = new Template( $this->renderer, $email->get_template_attributes() ); + + try { + $success = wp_mail( + $email->get_recipients(), + $email->get_subject(), + $email_template->get_body( $email->get_content() ), + $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 ); + } + +} diff --git a/templates/html/default.php b/templates/html/email-content.php similarity index 100% rename from templates/html/default.php rename to templates/html/email-content.php diff --git a/templates/html/email-footer.php b/templates/html/email-footer.php index e5aab55503c0b7d692076e03de17219f28fc689f..c6b9aeaea464d764893c196bb12de68cf7d6be44 100644 --- a/templates/html/email-footer.php +++ b/templates/html/email-footer.php @@ -1,18 +1,6 @@ <?php /** * Email Footer - * - * This template can be overridden by copying it to yourtheme/woocommerce/emails/email-footer.php. - * - * HOWEVER, on occasion WooCommerce will need to update template files and you - * (the theme developer) will need to copy the new files to your theme to - * maintain compatibility. We try to do this as little as possible, but it does - * happen. When this occurs the version of the template file will be bumped and - * the readme will list any important changes. - * - * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce\Templates\Emails - * @version 3.7.0 */ defined( 'ABSPATH' ) || exit; diff --git a/templates/html/email-header.php b/templates/html/email-header.php index d73b5a0f780ba83a7e1a9f7db3c8c11a840da03f..10b8088fd6d6640e3976474918f1899da872c530 100644 --- a/templates/html/email-header.php +++ b/templates/html/email-header.php @@ -1,18 +1,6 @@ <?php /** * Email Header - * - * This template can be overridden by copying it to yourtheme/woocommerce/emails/email-header.php. - * - * HOWEVER, on occasion WooCommerce will need to update template files and you - * (the theme developer) will need to copy the new files to your theme to - * maintain compatibility. We try to do this as little as possible, but it does - * happen. When this occurs the version of the template file will be bumped and - * the readme will list any important changes. - * - * @see https://docs.woocommerce.com/document/template-structure/ - * @package WooCommerce\Templates\Emails - * @version 4.0.0 */ if ( ! defined( 'ABSPATH' ) ) { diff --git a/templates/html/email-styles.php b/templates/html/email-styles.php index 2fae35bd616851f16ea1ebf68ec8d228de5ff00c..5a204dc46b4f59fb70e272bd8733879c982db83f 100644 --- a/templates/html/email-styles.php +++ b/templates/html/email-styles.php @@ -1,6 +1,6 @@ <?php -use WPDesk\Library\WPEmail\Helpers\Template; +use WPDesk\Library\WPEmail\Helpers\ColorConversion; $params = isset( $params ) ? $params : []; @@ -12,22 +12,22 @@ if ( ! defined( 'ABSPATH' ) ) { $bg = $params['bg'] ?? '#f8f8f8'; $body = $params['body'] ?? '#ffffff'; $base = $params['primary'] ?? '#5c9a2c'; -$base_text = Template::light_or_dark( $base, '#171717', '#ffffff' ); +$base_text = ColorConversion::light_or_dark( $base, '#171717', '#ffffff' ); $text = $params['text'] ?? '#33333'; // Pick a contrasting color for links. -$link_color = Template::is_hex_light( $base ) ? $base : $base_text; +$link_color = ColorConversion::is_hex_light( $base ) ? $base : $base_text; -if ( Template::is_hex_light( $body ) ) { - $link_color = Template::is_hex_light( $base ) ? $base_text : $base; +if ( ColorConversion::is_hex_light( $body ) ) { + $link_color = ColorConversion::is_hex_light( $base ) ? $base_text : $base; } -$bg_darker_10 = Template::hex_darker( $bg, 10 ); -$body_darker_10 = Template::hex_darker( $body, 10 ); -$base_lighter_20 = Template::hex_lighter( $base, 20 ); -$base_lighter_40 = Template::hex_lighter( $base, 40 ); -$text_lighter_20 = Template::hex_lighter( $text, 20 ); -$text_lighter_40 = Template::hex_lighter( $text, 40 ); +$bg_darker_10 = ColorConversion::hex_darker( $bg, 10 ); +$body_darker_10 = ColorConversion::hex_darker( $body, 10 ); +$base_lighter_20 = ColorConversion::hex_lighter( $base, 20 ); +$base_lighter_40 = ColorConversion::hex_lighter( $base, 40 ); +$text_lighter_20 = ColorConversion::hex_lighter( $text, 20 ); +$text_lighter_40 = ColorConversion::hex_lighter( $text, 40 ); // !important; is a gmail hack to prevent styles being stripped if it doesn't like something. // body{padding: 0;} ensures proper scale/positioning of the email in the iOS native email app. diff --git a/templates/plain/default.php b/templates/plain/email-content.php similarity index 100% rename from templates/plain/default.php rename to templates/plain/email-content.php diff --git a/tests/unit/Mailer/ColorTest.php b/tests/unit/Mailer/ColorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..940c1b7929923abfff2dc6c915dee38f942e6721 --- /dev/null +++ b/tests/unit/Mailer/ColorTest.php @@ -0,0 +1,51 @@ +<?php + +namespace Tests\Mailer; + +use PHPUnit\Framework\TestCase; +use WPDesk\Library\WPEmail\Helpers\ColorConversion; + +class ColorTest extends TestCase { + + public function testShouldCheckHexConversion() { + $white_hex = ColorConversion::rgb_from_hex( '#FFFFFF' ); + $white_rgb = [ + 'R' => 255, + 'G' => 255, + 'B' => 255, + ]; + $this->assertSame( $white_hex, $white_rgb ); + + $black_hex = ColorConversion::rgb_from_hex( '#000000' ); + $black_rgb = [ + 'R' => 0, + 'G' => 0, + 'B' => 0, + ]; + $this->assertSame( $black_hex, $black_rgb ); + } + + + public function testShouldCheckIsHexIsDarker() { + $dark_hex = ColorConversion::is_hex_light( '#333333' ); + $this->assertFalse( $dark_hex ); + } + + + public function testShouldCheckIsHexIsLighter() { + $light_hex = ColorConversion::is_hex_light( '#f8f8f8' ); + $this->assertTrue( $light_hex ); + } + + public function testShouldMakeColorDarker() { + $dark_hex = ColorConversion::hex_darker( '#f8f8f8' ); + $this->assertSame( $dark_hex, '#aeaeae' ); + } + + + public function testShouldMakeColorLighter() { + $light_hex = ColorConversion::hex_lighter( '#f8f8f8' ); + $this->assertSame( $light_hex, '#fafafa' ); + } + +} diff --git a/tests/unit/Mailer/MailTest.php b/tests/unit/Mailer/MailTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5397f3adcfed201559086f208a4a1d3ea21f0a01 --- /dev/null +++ b/tests/unit/Mailer/MailTest.php @@ -0,0 +1,87 @@ +<?php + +namespace Tests\Mailer; + +use PHPUnit\Framework\TestCase; +use WPDesk\Library\WPEmail\Abstracts\Email; + +class MailTest extends TestCase { + + const FROM = 'anna.nowak@gmail.com'; + const FROM_NAME = 'Anna Nowak'; + const RECIPIENTS = [ 'jan.nowak@gmail.com' ]; + const SUBJECT = 'Some Subject'; + const CONTENT = 'Lorem ipsum'; + + public $email; + + public function setUp(): void { + parent::setUp(); + \WP_Mock::setUp(); + $this->email = new Email(); + } + + public function testSetAndGetFromEmail(): void { + $data = \WP_Mock::userFunction('sanitize_email')->andReturn(''); + print_r( $data ); + exit; + \WP_Mock::passthruFunction( 'sanitize_email' ); + $this->email->set_from( 'john@example.com' ); + $this->assertEquals( 'john@example.com', $this->email->get_from() ); + } + + public function testSetAndGetFromName(): void { + \WP_Mock::passthruFunction( 'wp_specialchars_decode' ); + $this->email->set_from_name( 'John Doe' ); + $this->assertEquals( 'John Doe', $this->email->get_from_name() ); + } + + public function testSetAndGetSubject(): void { + $this->email->set_subject( 'Hello World' ); + $this->assertEquals( 'Hello World', $this->email->get_subject() ); + } + + public function testSetAndGetRecipients(): void { + $this->email->set_recipients( [ 'jane@example.com', 'mark@example.com' ] ); + $this->assertEquals( [ 'jane@example.com', 'mark@example.com' ], $this->email->get_recipients() ); + } + + public function testSetAndGetHeader(): void { + $this->email->set_header( 'Return-Path', 'mail@testsite.com' ); + $this->assertEquals( 'mail@testsite.com', $this->email->get_header( 'Return-Path' ) ); + } + + public function testSetAndGetAttachments(): void { + $this->email->set_attachments( [ 'file1.txt', 'file2.jpg' ] ); + $this->assertEquals( [ 'file1.txt', 'file2.jpg' ], $this->email->get_attachments() ); + } + + public function testIsHtml(): void { + $this->email->set_content_type(); + $this->assertTrue( $this->email->is_html() ); + + $this->email->set_content_type( 'plain' ); + $this->assertFalse( $this->email->is_html() ); + } + + public function testSetAndGetContentType(): void { + $this->email->set_content_type( 'html' ); + $this->assertEquals( 'text/html', $this->email->get_header( 'Content-Type' ) ); + + $this->email->set_content_type( 'plain' ); + $this->assertEquals( 'text/plain', $this->email->get_header( 'Content-Type' ) ); + + $this->email->set_content_type( 'multipart' ); + $this->assertEquals( 'multipart/alternative', $this->email->get_header( 'Content-Type' ) ); + } + + public function testSetAndGetContent(): void { + $this->email->set_content( 'Hello World' ); + $this->assertEquals( 'Hello World', $this->email->get_content() ); + } + + public function tearDown(): void { + \WP_Mock::tearDown(); + } + +} diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 76b8109582ae17560b77a6e0499b232e09047810..38a4eb0d02d4281e3ff45d89ea6ee201737e2750 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -5,5 +5,22 @@ require_once __DIR__ . '/../../vendor/autoload.php'; +error_reporting( E_ALL ); + +if ( getenv( 'PLUGIN_PATH' ) !== false ) { + define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) ); +} else { + define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); +} + +if ( getenv( 'ABSPATH' ) !== false ) { + define( 'ABSPATH', getenv( 'ABSPATH' ) ); +} else { + define( 'ABSPATH', PLUGIN_PATH . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); +} + WP_Mock::setUsePatchwork( true ); WP_Mock::bootstrap(); + + +