diff --git a/application/Espo/Core/Mail/EmailSender.php b/application/Espo/Core/Mail/EmailSender.php index 8f5c00141b..fb025ca919 100644 --- a/application/Espo/Core/Mail/EmailSender.php +++ b/application/Espo/Core/Mail/EmailSender.php @@ -104,17 +104,19 @@ class EmailSender /** * With parameters. * - * Available parameters: fromAddress, fromName, replyToAddress, replyToName. + * @param SenderParams|array $params */ - public function withParams(array $params = []): Sender + public function withParams($params): Sender { return $this->createSender()->withParams($params); } /** * With specific SMTP parameters. + * + * @param SmtpParams|array $params */ - public function withSmtpParams(array $params = []): Sender + public function withSmtpParams($params): Sender { return $this->createSender()->withSmtpParams($params); } diff --git a/application/Espo/Core/Mail/Sender.php b/application/Espo/Core/Mail/Sender.php index 6fca175df8..ec09dfd923 100644 --- a/application/Espo/Core/Mail/Sender.php +++ b/application/Espo/Core/Mail/Sender.php @@ -60,6 +60,7 @@ use Espo\Core\{ }; use Exception; +use InvalidArgumentException; /** * Sends emails. Builds parameters for sending. Should not be used directly. @@ -139,10 +140,17 @@ class Sender /** * With parameters. * - * Available parameters: fromAddress, fromName, replyToAddress, replyToName. + * @param SenderParams|array $params */ - public function withParams(array $params): self + public function withParams($params): self { + if ($params instanceof SenderParams) { + $params = $params->toArray(); + } + else if (!is_array($params)) { + throw new InvalidArgumentException(); + } + $paramList = [ 'fromAddress', 'fromName', @@ -150,7 +158,7 @@ class Sender 'replyToName', ]; - foreach ($params as $key => $value) { + foreach (array_keys($params) as $key) { if (!in_array($key, $paramList)) { unset($params[$key]); } @@ -163,9 +171,18 @@ class Sender /** * With specific SMTP parameters. + * + * @param SmtpParams|array $params */ - public function withSmtpParams(array $params): self + public function withSmtpParams($params): self { + if ($params instanceof SmtpParams) { + $params = $params->toArray(); + } + else if (!is_array($params)) { + throw new InvalidArgumentException(); + } + return $this->useSmtp($params); } diff --git a/application/Espo/Core/Mail/SenderParams.php b/application/Espo/Core/Mail/SenderParams.php new file mode 100644 index 0000000000..abb5945144 --- /dev/null +++ b/application/Espo/Core/Mail/SenderParams.php @@ -0,0 +1,135 @@ +paramList as $name) { + if ($this->$name !== null) { + $params[$name] = $this->$name; + } + } + + return $params; + } + + public static function fromArray(array $params): self + { + $obj = new self(); + + foreach ($obj->paramList as $name) { + if (array_key_exists($name, $params)) { + $obj->$name = $params[$name]; + } + } + + return $obj; + } + + public function getFromAddress(): ?string + { + return $this->fromAddress; + } + + public function getFromName(): ?string + { + return $this->fromName; + } + + public function getReplyToAddress(): ?string + { + return $this->replyToAddress; + } + + public function getReplyToName(): ?string + { + return $this->replyToName; + } + + public function withFromAddress(?string $fromAddress): self + { + $obj = clone $this; + + $obj->fromAddress = $fromAddress; + + return $obj; + } + + public function withFromName(?string $fromName): self + { + $obj = clone $this; + + $obj->fromName = $fromName; + + return $obj; + } + + public function withReplyToAddress(?string $replyToAddress): self + { + $obj = clone $this; + + $obj->replyToAddress = $replyToAddress; + + return $obj; + } + + public function withReplyToName(?string $replyToName): self + { + $obj = clone $this; + + $obj->replyToName = $replyToName; + + return $obj; + } +} diff --git a/application/Espo/Core/Mail/SmtpParams.php b/application/Espo/Core/Mail/SmtpParams.php new file mode 100644 index 0000000000..4a413e424b --- /dev/null +++ b/application/Espo/Core/Mail/SmtpParams.php @@ -0,0 +1,262 @@ +server = $server; + $this->port = $port; + } + + public static function create(string $server, int $port): self + { + return new self($server, $port); + } + + public function toArray(): array + { + $params = []; + + foreach ($this->paramList as $name) { + if ($this->$name !== null) { + $params[$name] = $this->$name; + } + } + + return $params; + } + + public static function fromArray(array $params): self + { + $server = $params['server'] ?? null; + $port = $params['port'] ?? null; + $auth = $params['auth'] ?? false; + + if ($server === null) { + throw new RuntimeException("Empty server."); + } + + if ($port === null) { + throw new RuntimeException("Empty port."); + } + + $obj = new self($server, $port); + + $obj->auth = $auth; + + foreach ($obj->paramList as $name) { + if ($obj->$name !== null) { + continue; + } + + if (array_key_exists($name, $params)) { + $obj->$name = $params[$name]; + } + } + + return $obj; + } + + public function getServer(): string + { + return $this->server; + } + + public function getPort(): int + { + return $this->port; + } + + public function getFromAddress(): ?string + { + return $this->fromAddress; + } + + public function getFromName(): ?string + { + return $this->fromName; + } + + public function getConnectionOptions(): ?array + { + return $this->connectionOptions; + } + + public function useAuth(): bool + { + return $this->auth; + } + + public function getAuthMechanism(): ?string + { + return $this->authMechanism; + } + + public function getAuthClassName(): ?string + { + return $this->authClassName; + } + + public function getUsername(): ?string + { + return $this->username; + } + + public function getPassword(): ?string + { + return $this->password; + } + + public function getSecurity(): ?string + { + return $this->security; + } + + public function withFromAddress(?string $fromAddress): self + { + $obj = clone $this; + + $obj->fromAddress = $fromAddress; + + return $obj; + } + + public function withFromName(?string $fromName): self + { + $obj = clone $this; + + $obj->fromName = $fromName; + + return $obj; + } + + public function withConnectionOptions(?array $connectionOptions): self + { + $obj = clone $this; + + $obj->connectionOptions = $connectionOptions; + + return $obj; + } + + public function withAuth(bool $auth = true): self + { + $obj = clone $this; + + $obj->auth = $auth; + + return $obj; + } + + public function withAuthMechanism(?string $authMechanism): self + { + $obj = clone $this; + + $obj->authMechanism = $authMechanism; + + return $obj; + } + + public function withAuthClassName(?string $authClassName): self + { + $obj = clone $this; + + $obj->authClassName = $authClassName; + + return $obj; + } + + public function withUsername(?string $username): self + { + $obj = clone $this; + + $obj->username = $username; + + return $obj; + } + + public function withPassword(?string $password): self + { + $obj = clone $this; + + $obj->password = $password; + + return $obj; + } + + public function withSecurity(?string $security): self + { + $obj = clone $this; + + $obj->security = $security; + + return $obj; + } +} diff --git a/tests/unit/Espo/Core/Mail/SenderParamsTest.php b/tests/unit/Espo/Core/Mail/SenderParamsTest.php new file mode 100644 index 0000000000..bf3a26adff --- /dev/null +++ b/tests/unit/Espo/Core/Mail/SenderParamsTest.php @@ -0,0 +1,72 @@ + 'test@test', + 'fromName' => 'name', + 'replyToAddress' => 'reply@test', + 'replyToName' => 'reply', + ]; + + $this->assertEquals($array, SenderParams::fromArray($array)->toArray()); + } + + public function testFromArray2(): void + { + $array = [ + 'fromAddress' => 'test@test', + 'fromName' => 'name', + ]; + + $this->assertEquals($array, SenderParams::fromArray($array)->toArray()); + } + + public function testBuilding(): void + { + $params = SenderParams::create() + ->withFromAddress('test@test') + ->withFromName('name') + ->withReplyToAddress('r@test') + ->withReplyToName('r'); + + $this->assertEquals('test@test', $params->getFromAddress()); + $this->assertEquals('name', $params->getFromName()); + + $this->assertEquals('r@test', $params->getReplyToAddress()); + $this->assertEquals('r', $params->getReplyToName()); + } +} diff --git a/tests/unit/Espo/Core/Mail/SmtpParamsTest.php b/tests/unit/Espo/Core/Mail/SmtpParamsTest.php new file mode 100644 index 0000000000..6fc38f070b --- /dev/null +++ b/tests/unit/Espo/Core/Mail/SmtpParamsTest.php @@ -0,0 +1,93 @@ + 'localhost', + 'port' => 587, + 'fromAddress' => 'test@test', + 'fromName' => 'name', + 'auth' => false, + ]; + + $this->assertEquals($array, SmtpParams::fromArray($array)->toArray()); + } + + public function testFromArray2(): void + { + $array = [ + 'server' => 'localhost', + 'port' => 587, + 'fromAddress' => 'test@test', + 'fromName' => 'name', + 'auth' => true, + 'connectionOptions' => ['test' => 'test'], + 'authMechanism' => 'login', + 'authClassName' => 'Test', + 'username' => 'tester', + 'password' => 'password', + 'security' => 'ssl', + ]; + + $this->assertEquals($array, SmtpParams::fromArray($array)->toArray()); + } + + public function testBuilding(): void + { + $params = SmtpParams::create('localhost', 587) + ->withFromAddress('test@test') + ->withFromName('name') + ->withAuth() + ->withUsername('tester') + ->withPassword('test') + ->withAuthMechanism('login') + ->withAuthClassName('Test') + ->withConnectionOptions(['test' => 'test']); + + $this->assertEquals('localhost', $params->getServer()); + $this->assertEquals(587, $params->getPort()); + + $this->assertEquals('test@test', $params->getFromAddress()); + $this->assertEquals('name', $params->getFromName()); + + $this->assertEquals(true, $params->useAuth()); + + $this->assertEquals('tester', $params->getUsername()); + $this->assertEquals('test', $params->getPassword()); + $this->assertEquals(['test' => 'test'], $params->getConnectionOptions()); + $this->assertEquals('Test', $params->getAuthClassName()); + } +}