diff --git a/.gitignore b/.gitignore index 73d1b1b..362d7b9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ composer.lock php-cs-fixer-v2.phar .idea/* php-cs-fixer.phar +clover.xml +tests/webfiori/tests/mail/Hello Email Message/* +.php_cs.cache diff --git a/tests/webfiori/tests/mail/EmailMessageTest.php b/tests/webfiori/tests/mail/EmailMessageTest.php index 150ceda..7e9b3e1 100644 --- a/tests/webfiori/tests/mail/EmailMessageTest.php +++ b/tests/webfiori/tests/mail/EmailMessageTest.php @@ -4,8 +4,10 @@ use PHPUnit\Framework\TestCase; use webfiori\email\Email; use webfiori\email\exceptions\SMTPException; +use webfiori\email\SendMode; use webfiori\email\SMTPAccount; use webfiori\email\SMTPServer; +use webfiori\file\exceptions\FileException; use webfiori\file\File; /** * A test class for testing the class 'webfiori\framework\mail\EmailMessage'. @@ -433,4 +435,110 @@ public function testTemplate03() { . ''.SMTPServer::NL, $message.''); } + /** + * @test + */ + public function testStoreMode00() { + $message = new Email(); + $this->assertEquals(SendMode::PROD, $message->getMode()); + $this->assertTrue($message->setMode(SendMode::TEST_STORE, [ + 'store-path' => __DIR__ + ])); + $this->assertEquals(SendMode::TEST_STORE, $message->getMode()); + $message->send(); + $this->assertTrue(File::isFileExist(__DIR__.DIRECTORY_SEPARATOR.$message->getSubject().DIRECTORY_SEPARATOR.date('Y-m-d H-i-s').'.html')); + } + /** + * @test + */ + public function testStoreMode01() { + $this->expectException(FileException::class); + $this->expectExceptionMessage('Store path is not set for mode SendMode::TEST_STORE.'); + $message = new Email(); + $this->assertEquals(SendMode::PROD, $message->getMode()); + $this->assertTrue($message->setMode(SendMode::TEST_STORE, [ + + ])); + $this->assertEquals(SendMode::TEST_STORE, $message->getMode()); + $message->send(); + $this->assertTrue(File::isFileExist(__DIR__.DIRECTORY_SEPARATOR.$message->getSubject().DIRECTORY_SEPARATOR.date('Y-m-d H-i-s').'.html')); + } + /** + * @test + */ + public function testStoreMode02() { + $this->expectException(FileException::class); + $this->expectExceptionMessage('Store path does not exist: \''.__DIR__.DIRECTORY_SEPARATOR.'inv_p\''); + $message = new Email(); + $this->assertEquals(SendMode::PROD, $message->getMode()); + $this->assertTrue($message->setMode(SendMode::TEST_STORE, [ + 'store-path' => __DIR__.DIRECTORY_SEPARATOR.'inv_p' + ])); + $this->assertEquals(SendMode::TEST_STORE, $message->getMode()); + $message->send(); + } + /** + * @test + */ + public function testSendMode00() { + $message = new Email(new SMTPAccount($this->acc01)); + $this->assertTrue($message->setMode(SendMode::TEST_SEND, [ + 'send-addresses' => [ + 'ibinshikh@outlook.com' + ] + ])); + $this->assertEquals(SendMode::TEST_SEND, $message->getMode()); + $message->send(); + $this->assertEquals([ + 'command' => 'QUIT', + 'code' => 221, + 'message' => '221 gator4189.hostgator.com closing connection', + 'time' => date('Y-m-d H:i:s'), + ], $message->getSMTPServer()->getLastLogEntry()); + $this->assertTrue(true); + } + /** + * @test + */ + public function testSendMode01() { + $message = new Email(new SMTPAccount($this->acc01)); + $this->assertTrue($message->setMode(SendMode::TEST_SEND, [ + 'send-addresses' => 'ibinshikh@outlook.com' + ])); + $this->assertEquals(SendMode::TEST_SEND, $message->getMode()); + $message->send(); + $this->assertEquals([ + 'command' => 'QUIT', + 'code' => 221, + 'message' => '221 gator4189.hostgator.com closing connection', + 'time' => date('Y-m-d H:i:s'), + ], $message->getSMTPServer()->getLastLogEntry()); + $this->assertTrue(true); + } + /** + * @test + */ + public function testSendMode02() { + $this->expectException(SMTPException::class); + $this->expectExceptionMessage('Recipients are not set for mode SendMode::TEST_SEND.'); + $message = new Email(new SMTPAccount($this->acc01)); + $this->assertTrue($message->setMode(SendMode::TEST_SEND, [ + + ])); + $this->assertEquals(SendMode::TEST_SEND, $message->getMode()); + $message->send(); + } } + + + + + + + + + + + + + diff --git a/webfiori/email/Email.php b/webfiori/email/Email.php index 708cb8a..d199f82 100644 --- a/webfiori/email/Email.php +++ b/webfiori/email/Email.php @@ -1,6 +1,7 @@ beforeSendPool = []; $this->afterSendPool = []; $this->document = new HTMLDoc(); + $this->mode = SendMode::PROD; + $this->modeConfig = []; if ($sendAccount !== null) { $this->setSMTPAccount($sendAccount); @@ -371,6 +376,41 @@ public function getLang() { public function getLog() : array { return $this->getSMTPServer()->getLog(); } + /** + * Returns the mode at which the message will use when the method 'send' is called. + * + * @return string The method will return one of 3 values: + * + * + */ + public function getMode() : string { + return $this->mode; + } + /** + * Returns an array that holds the configuration of send mode of the message. + * + * Possible indices of the are: + * + * + * @return array An associative array. + */ + public function getModeConfig() : array { + return $this->modeConfig; + } /** * Returns the priority of the message. * @@ -541,52 +581,52 @@ public function removeAllRecipients() { /** * Sends the message. * - * Note that if in testing environment, the method will attempt to store - * the email as HTML web page. Testing environment is set when the constant - * EMAIL_TESTING is defined and set to true in addition to having the - * constant EMAIL_TESTING_PATH defined. - * - * Additionally, the email can be sent to specific address by - * defining the constant EMAIL_TESTING_ADDRESS. - * */ public function send() { $this->invokeBeforeSend(); - if (defined('EMAIL_TESTING') && EMAIL_TESTING === true) { - $isStore = defined('EMAIL_TESTING_PATH') && File::isDirectory(EMAIL_TESTING_PATH, true); - $isSend = defined('EMAIL_TESTING_ADDRESS'); - $this->setupBeoreTesting(); + $sendMode = $this->getMode(); - if ($isSend) { - $this->removeAllRecipients(); - $addresees = explode(';', EMAIL_TESTING_ADDRESS); + if ($sendMode == SendMode::TEST_STORE) { + $config = $this->getModeConfig(); - foreach ($addresees as $addr) { - $trimmed = trim($addr); + if (!isset($config['store-path'])) { + throw new FileException('Store path is not set for mode SendMode::TEST_STORE.'); + } + $path = $config['store-path']; - if (strlen($trimmed) != 0) { - $this->addTo($trimmed); - } - } + if (!File::isDirectory($path)) { + throw new FileException('Store path does not exist: \''.$path.'\''); } + $this->setupBeoreTesting(); + $this->storeEmail($path); + $this->invokeAfterSend(); - if ($isStore && File::isDirectory(EMAIL_TESTING_PATH, true)) { - $this->storeEmail(EMAIL_TESTING_PATH); - } else { - throw new FileException('"EMAIL_TESTING_PATH" is not valid.'); + return; + } else if ($sendMode == SendMode::TEST_SEND) { + $config = $this->getModeConfig(); + + if (!isset($config['send-addresses'])) { + throw new SMTPException('Recipients are not set for mode SendMode::TEST_SEND.'); } + $rcpt = $config['send-addresses']; + + if (gettype($rcpt) == 'string') { + $rcpt = explode(';', $rcpt); + } + $this->setupBeoreTesting(); + $this->removeAllRecipients(); - if (!$isSend) { - $this->invokeAfterSend(); + foreach ($rcpt as $addr) { + $trimmed = trim($addr); - return; + if (strlen($trimmed) != 0) { + $this->addTo($trimmed); + } } - } + } $acc = $this->getSMTPAccount(); - - $server = $this->getSMTPServer(); if ($this->rcptCount() == 0) { @@ -644,6 +684,45 @@ public function setLang(string $langCode = 'EN') : Email { return $this; } + /** + * Sets the mode at which the message will use when the send method is called. + * + * @param string $mode This can be one of 3 values: + * + * + * @param array $config An array that holds send option configuration. + * The array can have following indices: + * + * + * @return bool If the mode successfully updated, true is returned. + * Other than that, false is returned. + */ + public function setMode(string $mode, array $config = []) : bool { + $trimmed = strtolower(trim($mode)); + + if ($mode == SendMode::PROD || $mode == SendMode::TEST_SEND || $mode == SendMode::TEST_STORE) { + $this->mode = $trimmed; + $this->modeConfig = $config; + + return true; + } + + return false; + } /** * Sets the priority of the message. * @@ -790,7 +869,10 @@ private function priorityCommandHelper(): string { } else { $importanceHeaderVal = 'normal'; } - $this->getSMTPServer()->sendCommand('Priority: '.$priorityHeaderVal); + try { + $this->getSMTPServer()->sendCommand('Priority: '.$priorityHeaderVal); + } catch (TypeError $ex) { + } return $importanceHeaderVal; } @@ -806,11 +888,20 @@ private function receiversCommandHelper($type) { } } private function setupBeoreTesting() { - $acc = $this->getSMTPAccount(); + try { + $acc = $this->getSMTPAccount(); + } catch (TypeError $ex) { + $acc = null; + } $headersTable = new HeadersTable(); $headersTable->addHeader('Importance', $this->priorityCommandHelper()); - $headersTable->addHeader('From', $acc->getSenderName().' <'.$acc->getAddress().'>'); + + if ($acc !== null) { + $headersTable->addHeader('From', $acc->getSenderName().' <'.$acc->getAddress().'>'); + } else { + $headersTable->addHeader('From', ' '); + } $headersTable->addHeader('To', $this->getReceiversStrHelper('to', false)); $headersTable->addHeader('CC', $this->getReceiversStrHelper('cc', false)); $headersTable->addHeader('BCC', $this->getReceiversStrHelper('bcc', false)); diff --git a/webfiori/email/SendMode.php b/webfiori/email/SendMode.php new file mode 100644 index 0000000..b7edb45 --- /dev/null +++ b/webfiori/email/SendMode.php @@ -0,0 +1,26 @@ +