* @link https://www.oxidmodule.com */ declare(strict_types=1); namespace D3\MailConfigChecker\Application\Controller\Admin; use Assert\Assert; use Assert\InvalidArgumentException; use D3\MailConfigChecker\Application\Model\Constants; use Net_SMTP; use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController; use OxidEsales\Eshop\Application\Model\Shop; use OxidEsales\Eshop\Core\Registry; use PEAR; use PEAR_Error; class SmtpChecker extends AdminDetailsController { protected bool $debug = true; protected string $host; protected int $port; protected string $user; protected string $pwd; protected string $from; protected ?string $to = null; protected Net_SMTP $smtp; protected string $action = ''; protected array $log = []; public function __construct() { parent::__construct(); /** @var Shop $activeShop */ $activeShop = Registry::getConfig()->getActiveShop(); if ($localHost = Registry::getRequest()->getRequestEscapedParameter('smtpHost')) { ['host' => $shopHost, 'port' => $shopPort] = parse_url(trim($localHost)); } else { ['host' => $shopHost, 'port' => $shopPort] = parse_url(trim($activeShop->getFieldData('oxsmtp'))); } $this->host = $shopHost; $this->addTplParam('smtpHost', Registry::getRequest()->getRequestEscapedParameter('smtpHost')); $this->port = $shopPort; $this->user = Registry::getRequest()->getRequestEscapedParameter('smtpUser') ?: $activeShop->getFieldData('oxsmtpuser'); $this->addTplParam('smtpUser', $this->user); $this->pwd = Registry::getRequest()->getRequestEscapedParameter('smtpPwd') ?: $activeShop->getFieldData('oxsmtppwd'); $this->addTplParam('smtpPwd', $this->pwd); $this->from = Registry::getRequest()->getRequestEscapedParameter('from') ?: ''; $this->addTplParam('from', $this->from); $this->to = Registry::getRequest()->getRequestEscapedParameter('to') ?: ''; $this->addTplParam('recipient', $this->to); $this->addTplParam('sendMail', Registry::getRequest()->getRequestEscapedParameter('sendmail')); $this->addTplParam('smtpLog', $this->log); } public function getTemplateName(): string { return '@'.Constants::OXID_MODULE_ID.'/admin/smtpCheck'; } public function render(): ?string { $this->addTplParam('shop', Registry::getConfig()->getActiveShop()); return parent::render(); } public function getMailAddressList(): array { /** @var Shop $shop */ $shop = Registry::getConfig()->getActiveShop(); return array_filter( array_unique( [ $shop->getFieldData('oxinfoemail'), $shop->getFieldData('oxorderemail'), $shop->getFieldData('oxowneremail'), ] ) ); } public function sendMail(): void { try { $this->hostIsAvailable(); $this->connect(); $this->auth(); $this->setFrom(); $this->setRecipient(); $this->sendContent(); $this->addTplParam('success', true); } catch (InvalidArgumentException $e) { Registry::getUtilsView()->addErrorToDisplay($e); } finally { $this->disconnect(); } $this->addTplParam('smtpLog', $this->log); } /** * @throws InvalidArgumentException * @return void */ protected function hostIsAvailable(): void { $this->action = __FUNCTION__; Assert::that( ($this->smtp = new Net_SMTP($this->host, $this->port, $_SERVER['HTTP_HOST'])), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_INSTANCE') )->isInstanceOf( Net_SMTP::class, Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NOCONNECTION') ); $this->smtp->setDebug($this->debug, [$this, 'dumpDebug']); } protected function connect(): void { $this->action = __FUNCTION__; Assert::that( $this->smtp->connect(), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_CONNECTION') )->notIsInstanceOf( PEAR_Error::class, [$this, 'formatMessage'], Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NOCONNECTION') ); } /** * @throws InvalidArgumentException * @return void */ protected function auth(): void { $this->action = __FUNCTION__; Assert::that( $this->smtp->auth($this->user, $this->pwd), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_AUTHENTICATION') )->notIsInstanceOf( PEAR_Error::class, [$this, 'formatMessage'], Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NOAUTHENTICATION') ); } protected function setFrom(): void { $this->action = __FUNCTION__; Assert::that( $this->smtp->mailFrom($this->from), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_SENDER') )->notIsInstanceOf( PEAR_Error::class, [$this, 'formatMessage'], sprintf(Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NOSENDER'), $this->from) ); } protected function setRecipient(): void { if (!$this->to) { return; } $this->action = __FUNCTION__; Assert::that( $this->smtp->rcptTo($this->to), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_RECIPIENT') )->notIsInstanceOf( PEAR_Error::class, [$this, 'formatMessage'], sprintf(Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NORECIPIENT'), $this->to) ); } protected function sendContent(): void { if (!Registry::getRequest()->getRequestEscapedParameter('sendmail')) { return; } $this->action = __FUNCTION__; $subj = "Subject: Test Message\n"; $body = "Body Line 1\nBody Line 2"; Assert::that( $this->smtp->data($subj . "\r\n" . $body), Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_TRANSMIT') )->notIsInstanceOf( PEAR_Error::class, [$this, 'formatMessage'], Registry::getLang()->translateString('D3_MAILCHECKER_SMTPCHECK_NOTRANSMIT') ); } protected function disconnect(): void { $this->action = __FUNCTION__; $this->smtp->disconnect(); } public function dumpDebug($smtp, $message): void { unset($smtp); if (!isset($this->log[$this->action])) { $this->log[$this->action] = []; } $this->log[$this->action][] = trim(htmlentities($message)); } public function formatMessage(array $arguments): ?string { /** @var PEAR_Error|true $response */ $response = $arguments['value']; $propertyPath = $arguments['propertyPath']; if (PEAR::isError($response)) { return ($propertyPath ? $propertyPath .' - ' : ''). $response->getMessage() . ($response->getCode() ? ': '.$response->getCode() : ''); } return null; } }