Compare commits

...

13 Commits

Author SHA1 Message Date
a314136829 Merge branch 'rel_2.x' into rel_3.x
# Conflicts:
#	CHANGELOG.md
#	metadata.php
2024-07-10 08:30:11 +02:00
c3649a9e24
set EHLO domain in SMTP check 2024-07-09 23:36:11 +02:00
a154a9a243
show communication protocol from shop 2024-07-09 23:33:17 +02:00
116001f0fe Merge branch 'rel_2.x' into rel_3.x 2024-06-05 08:47:59 +02:00
1d7a47c048 align version information 2024-06-05 08:43:27 +02:00
99744ada70 Merge branch 'rel_2.x' into dev_3.x_OX7
# Conflicts:
#	Application/Controller/Admin/SpfChecker.php
#	Application/Model/DmarcResult.php
2024-06-05 08:38:43 +02:00
d89b1a1848 add Twig templates 2024-06-04 15:38:19 +02:00
32d3b178f8 improve code 2024-06-04 14:37:41 +02:00
8900201ee8 add DMARC check 2024-06-04 14:20:20 +02:00
4e84b6940a align copyright notes 2024-06-03 07:57:58 +02:00
ab3c6e20a6 align Smarty template registration 2024-06-03 07:56:54 +02:00
46aeb7e6bd move assets 2024-05-31 16:30:51 +02:00
6bf8b0fb4c make installable in OXID 7 2024-05-31 16:02:53 +02:00
40 changed files with 745 additions and 172 deletions

View File

@ -1,17 +1,13 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
*
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
@ -19,11 +15,12 @@ declare(strict_types=1);
namespace D3\MailConfigChecker\Application\Controller\Admin;
use D3\MailConfigChecker\Application\Model\Constants;
use OxidEsales\Eshop\Application\Controller\Admin\AdminController;
class MailCheckBase extends AdminController
{
protected $_sThisTemplate = 'mailCheckBase.tpl';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailCheckBase';
/**
* @return string

View File

@ -1,17 +1,13 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
*
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
@ -19,13 +15,14 @@ declare(strict_types=1);
namespace D3\MailConfigChecker\Application\Controller\Admin;
use D3\MailConfigChecker\Application\Model\Constants;
use OxidEsales\Eshop\Application\Controller\Admin\AdminListController;
class MailCheckMenu extends AdminListController
{
protected $_sThisTemplate = 'mailCheckMenu.tpl';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailCheckMenu';
public function render()
public function render(): string
{
$this->setEditObjectId('foo');
return parent::render();

View File

@ -1,22 +1,21 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\MailConfigChecker\Application\Controller\Admin;
use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\MailConfigChecker\Application\Model\Constants;
use D3\MailConfigChecker\Application\Model\Exception\d3TranslatableLazyAssertionException;
use Exception;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
@ -26,10 +25,10 @@ use OxidEsales\Eshop\Core\Registry;
class MailConfigCheck extends AdminDetailsController
{
protected $_sThisTemplate = 'mailConfigCheck.tpl';
protected $testMailAddress = 'test@example.com';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailConfigCheck';
protected string $testMailAddress = 'test@example.com';
public function render()
public function render(): string
{
$this->checkDataAreSet();
$this->addTplParam('shop', Registry::getConfig()->getActiveShop());
@ -38,7 +37,7 @@ class MailConfigCheck extends AdminDetailsController
return parent::render();
}
protected function checkDataAreSet()
protected function checkDataAreSet(): void
{
try {
/** @var Shop $shop */
@ -66,12 +65,12 @@ class MailConfigCheck extends AdminDetailsController
}
}
public function checkConfiguration()
public function checkConfiguration(): void
{
$this->getCurrentMailer();
}
protected function getCurrentMailer()
protected function getCurrentMailer(): void
{
try {
$shop = Registry::getConfig()->getActiveShop();

View File

@ -1,23 +1,22 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\MailConfigChecker\Application\Controller\Admin;
use D3\MailConfigChecker\Application\Model\Constants;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
class MailInfoPage extends AdminDetailsController
{
protected $_sThisTemplate = 'mailInfoPage.tpl';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailInfoPage';
}

View File

@ -1,22 +1,22 @@
<?php
/**
* This Software is the property of Data Development and is protected
* by copyright law - it is NOT Freeware.
* Any unauthorized use of this software without a valid license
* is a violation of the license agreement and will be prosecuted by
* civil and criminal law.
* http://www.shopmodule.com
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
namespace D3\MailConfigChecker\Application\Controller\Admin;
use Assert\Assert;
use D3\MailConfigChecker\Application\Model\Constants;
use D3\MailConfigChecker\Application\Model\Exception\d3TranslatableLazyAssertionException;
use Exception;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Application\Model\Shop;
use OxidEsales\Eshop\Core\Email;
@ -24,9 +24,9 @@ use OxidEsales\Eshop\Core\Registry;
class MailTester extends AdminDetailsController
{
protected $_sThisTemplate = 'mailTester.tpl';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailTester';
public function sendMail()
public function sendMail(): void
{
try {
$request = Registry::getRequest();
@ -46,12 +46,12 @@ class MailTester extends AdminDetailsController
$mail->setFrom($from);
$mail->sendEmail($to, $subject, $body);
$this->addTplParam('success', true);
} catch (\Exception $e) {
} catch ( Exception $e) {
Registry::getUtilsView()->addErrorToDisplay(nl2br($e->getMessage()));
}
}
protected function assertContent()
protected function assertContent(): void
{
$request = Registry::getRequest();
$lang = Registry::getLang();
@ -77,7 +77,7 @@ class MailTester extends AdminDetailsController
->verifyNow();
}
public function getMailAddressList()
public function getMailAddressList(): array
{
/** @var Shop $shop */
$shop = Registry::getConfig()->getActiveShop();

View File

@ -17,6 +17,7 @@ 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;
@ -26,18 +27,18 @@ use PEAR_Error;
class SmtpChecker extends AdminDetailsController
{
protected $debug = true;
protected bool $debug = true;
protected $host;
protected $port;
protected $user;
protected $pwd;
protected $from;
protected $to;
protected string $host;
protected int $port;
protected string $user;
protected string $pwd;
protected string $from;
protected ?string $to = null;
protected $smtp;
protected $action;
protected $log = [];
protected Net_SMTP $smtp;
protected string $action = '';
protected array $log = [];
public function __construct()
{
@ -68,19 +69,19 @@ class SmtpChecker extends AdminDetailsController
$this->addTplParam('smtpLog', $this->log);
}
public function getTemplateName()
public function getTemplateName(): string
{
return 'smtpCheck.tpl';
return '@'.Constants::OXID_MODULE_ID.'/admin/smtpCheck';
}
public function render()
public function render(): ?string
{
$this->addTplParam('shop', Registry::getConfig()->getActiveShop());
return parent::render();
}
public function getMailAddressList()
public function getMailAddressList(): array
{
/** @var Shop $shop */
$shop = Registry::getConfig()->getActiveShop();
@ -96,7 +97,7 @@ class SmtpChecker extends AdminDetailsController
);
}
public function sendMail()
public function sendMail(): void
{
try {
$this->hostIsAvailable();
@ -119,7 +120,7 @@ class SmtpChecker extends AdminDetailsController
* @throws InvalidArgumentException
* @return void
*/
protected function hostIsAvailable()
protected function hostIsAvailable(): void
{
$this->action = __FUNCTION__;
Assert::that(
@ -132,7 +133,7 @@ class SmtpChecker extends AdminDetailsController
$this->smtp->setDebug($this->debug, [$this, 'dumpDebug']);
}
protected function connect()
protected function connect(): void
{
$this->action = __FUNCTION__;
Assert::that(
@ -149,7 +150,7 @@ class SmtpChecker extends AdminDetailsController
* @throws InvalidArgumentException
* @return void
*/
protected function auth()
protected function auth(): void
{
$this->action = __FUNCTION__;
Assert::that(
@ -162,7 +163,7 @@ class SmtpChecker extends AdminDetailsController
);
}
protected function setFrom()
protected function setFrom(): void
{
$this->action = __FUNCTION__;
Assert::that(
@ -175,8 +176,12 @@ class SmtpChecker extends AdminDetailsController
);
}
protected function setRecipient()
protected function setRecipient(): void
{
if (!$this->to) {
return;
}
$this->action = __FUNCTION__;
Assert::that(
$this->smtp->rcptTo($this->to),
@ -188,7 +193,7 @@ class SmtpChecker extends AdminDetailsController
);
}
protected function sendContent()
protected function sendContent(): void
{
if (!Registry::getRequest()->getRequestEscapedParameter('sendmail')) {
return;
@ -207,13 +212,13 @@ class SmtpChecker extends AdminDetailsController
);
}
protected function disconnect()
protected function disconnect(): void
{
$this->action = __FUNCTION__;
$this->smtp->disconnect();
}
public function dumpDebug($smtp, $message)
public function dumpDebug($smtp, $message): void
{
unset($smtp);
@ -223,7 +228,7 @@ class SmtpChecker extends AdminDetailsController
$this->log[$this->action][] = trim(htmlentities($message));
}
public function formatMessage(array $arguments)
public function formatMessage(array $arguments): ?string
{
/** @var PEAR_Error|true $response */
$response = $arguments['value'];

View File

@ -18,8 +18,10 @@ namespace D3\MailConfigChecker\Application\Controller\Admin;
use Assert\InvalidArgumentException;
use D3\MailAuthenticationCheck\DMARCCheck;
use D3\MailAuthenticationCheck\Model\DMARCResult;
use D3\MailConfigChecker\Application\Model\Constants;
use D3\MailConfigChecker\Application\Model\DmarcResult as OxDmarcResult;
use D3\MailConfigChecker\Application\Model\SpfResult;
use LogicException;
use Mika56\SPFCheck\DNS\DNSRecordGetter;
use Mika56\SPFCheck\Model\Query;
use Mika56\SPFCheck\Model\Result;
@ -30,16 +32,16 @@ use OxidEsales\Eshop\Core\Registry;
class SpfChecker extends AdminDetailsController
{
protected $_sThisTemplate = 'spfCheck.tpl';
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/spfCheck';
public function render()
public function render(): ?string
{
$this->checkSpf();
$this->checkDmarc();
return parent::render();
}
protected function checkSpf()
protected function checkSpf(): void
{
$result = [];
$mailDomains = $this->getMailDomains();
@ -53,7 +55,7 @@ class SpfChecker extends AdminDetailsController
$this->addTplParam('spf_result', $result);
}
protected function checkDmarc()
protected function checkDmarc(): void
{
$result = [];
$mailDomains = $this->getMailDomains();
@ -79,13 +81,13 @@ class SpfChecker extends AdminDetailsController
function ($mailAddress) {
$mailAddress = trim($mailAddress);
try {
if (! strstr($mailAddress, '@')) {
if ( ! str_contains( $mailAddress, '@' ) ) {
throw oxNew(InvalidArgumentException::class);
}
$addressChunks = explode('@', $mailAddress);
return array_pop($addressChunks);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException) {
return '';
}
},
@ -99,25 +101,17 @@ class SpfChecker extends AdminDetailsController
);
}
protected function checkSpfByDomain($domain, &$summarize)
protected function checkSpfByDomain($domain, &$summarize): void
{
$checker = new SPFCheck(new DNSRecordGetter());
$query = new Query('', $domain);
$result = $checker->getResult($query);
switch ($result->getResult()) {
case Result::FAIL:
case Result::NEUTRAL:
case Result::PASS:
case Result::SOFTFAIL:
$status = SpfResult::SET;
break;
case Result::NONE:
$status = SpfResult::MISSING;
break;
default:
$status = SpfResult::ERROR;
}
$status = match ( $result->getResult() ) {
Result::FAIL, Result::NEUTRAL, Result::PASS, Result::SOFTFAIL => SpfResult::SET,
Result::NONE => SpfResult::MISSING,
default => SpfResult::ERROR,
};
$rawRecord = ($record = $result->getRecord()) ?
$record->getRawRecord() :
@ -126,52 +120,40 @@ class SpfChecker extends AdminDetailsController
$summarize[$domain] = oxNew(SpfResult::class, $status, $rawRecord);
}
public function getSpfStatusColor(SpfResult $result)
public function getSpfStatusColor(SpfResult $result): string
{
switch ($result->getStatus()) {
case SpfResult::SET:
return 'success';
case SpfResult::ERROR:
return 'warning';
default:
return 'danger';
}
return match ( $result->getStatus() ) {
SpfResult::SET => 'success',
SpfResult::ERROR => 'warning',
default => 'danger',
};
}
public function checkDmarcByDomain($domain, &$summarize)
public function checkDmarcByDomain($domain, &$summarize): void
{
try {
$check = new DMARCCheck(new DNSRecordGetter());
$query = new Query('', $domain);
$record = $check->getResult($query)->getRecord();
switch ( $record->getRejectPolicy()->getValue() ) {
case DMARCResult::REJECT_QUARANTINE:
case DMARCResult::REJECT_REJECT:
$status = OxDmarcResult::SET;
break;
case DMARCResult::REJECT_NONE:
$status = OxDmarcResult::MISSING;
break;
default:
$status = OxDmarcResult::ERROR;
}
$status = match ( $record->getRejectPolicy()->getValue() ) {
DMARCResult::REJECT_QUARANTINE, DMARCResult::REJECT_REJECT => OxDmarcResult::SET,
DMARCResult::REJECT_NONE => OxDmarcResult::MISSING,
default => OxDmarcResult::ERROR,
};
$summarize[$domain] = oxNew( OxDmarcResult::class, $status, $record->getRawRecord());
} catch (\LogicException) {
} catch ( LogicException) {
$summarize[$domain] = oxNew( OxDmarcResult::class, OxDmarcResult::MISSING, '');
}
}
public function getDmarcStatusColor(OxDmarcResult $result)
public function getDmarcStatusColor(OxDmarcResult $result): string
{
switch ($result->getStatus()) {
case SpfResult::SET:
return 'success';
case SpfResult::ERROR:
return 'warning';
default:
return 'danger';
}
return match ( $result->getStatus() ) {
SpfResult::SET => 'success',
SpfResult::ERROR => 'warning',
default => 'danger',
};
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
namespace D3\MailConfigChecker\Application\Model;
class Constants
{
public const OXID_MODULE_ID = 'd3mailconfigchecker';
}

View File

@ -30,12 +30,12 @@ class DmarcResult
$this->record = $record;
}
public function getStatus()
public function getStatus(): string
{
return $this->status;
}
public function getRecord()
public function getRecord(): ?string
{
return $this->record;
}

View File

@ -21,8 +21,8 @@ class SpfResult
public const MISSING = 'missing';
public const ERROR = 'error';
protected $status;
protected $record;
protected string $status;
protected ?string $record;
public function __construct(string $status, ?string $record = null)
{
@ -30,12 +30,12 @@ class SpfResult
$this->record = $record;
}
public function getStatus()
public function getStatus(): string
{
return $this->status;
}
public function getRecord()
public function getRecord(): ?string
{
return $this->record;
}

View File

@ -1,3 +0,0 @@
<?php
$aLang = include __DIR__."/../../de/translations.php";

View File

@ -1,3 +0,0 @@
<?php
$aLang = include __DIR__."/../../en/translations.php";

View File

@ -0,0 +1,22 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
// @codeCoverageIgnoreStart
$sLangName = 'Deutsch';
$aLang = include __DIR__."/../../de/translations.php";
// @codeCoverageIgnoreEnd

View File

@ -0,0 +1,22 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
// @codeCoverageIgnoreStart
$sLangName = 'English';
$aLang = include __DIR__."/../../en/translations.php";
// @codeCoverageIgnoreEnd

View File

@ -0,0 +1,22 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
// @codeCoverageIgnoreStart
$sLangName = 'Deutsch';
$aLang = include __DIR__."/../../de/translations.php";
// @codeCoverageIgnoreEnd

View File

@ -0,0 +1,22 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
// @codeCoverageIgnoreStart
$sLangName = 'English';
$aLang = include __DIR__."/../../en/translations.php";
// @codeCoverageIgnoreEnd

View File

@ -1,5 +1,18 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
return [
'charset' => 'UTF-8',
'D3_MENU_MAILCHECKER' => 'E-Mail PrĂĽfung',

View File

@ -1,5 +1,18 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
*/
declare(strict_types=1);
return [
"charset" => "UTF-8",
"D3_MENU_MAILCHECKER" => "Email checking",

View File

@ -4,7 +4,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased](https://git.d3data.de/D3Public/MyModule/compare/2.1.1.0...rel_2.x)
## [Unreleased](https://git.d3data.de/D3Public/MyModule/compare/3.0.1.0...rel_3.x)
## [3.0.1.0](https://git.d3data.de/D3Public/MailConfigChecker/compare/3.0.0.0...3.0.1.0) - 2024-07-10
### Added
- get mailer check shows PHPMailer communication with the mail server (can be different from the SMTP check)
- recipient for get mailer check can modified in hidden form element
### Changed
- SMTP check uses shop domain for EHLO
## [3.0.0.0](https://git.d3data.de/D3Public/MailConfigChecker/compare/2.1.0.0...3.0.0.0) - 2024-06-05
### Added
- OXID 7.x support
- Twig templates (alongside to Smarty)
### Removed
- OXID 6.x support
## [2.1.1.0](https://git.d3data.de/D3Public/MailConfigChecker/compare/2.1.0.0...2.1.1.0) - 2024-07-10
### Added

View File

@ -19,7 +19,7 @@ Dieses Paket erfordert einen mit Composer installierten OXID eShop in einer in d
```bash
composer require d3/mailconfigchecker:^2.0
composer require d3/mailconfigchecker:^3.0
```
Aktivieren Sie das Modul im Shopadmin unter "Erweiterungen -> Module".

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -31,8 +31,8 @@
"GPL-3.0-or-later"
],
"require": {
"php": ">=7.3",
"oxid-esales/oxideshop-ce": "6.10 - 6.14",
"php": "^8",
"oxid-esales/oxideshop-ce": "7.0 - 7.1",
"pear/net_smtp": "^1.11",
"mika56/spfcheck": "^2.1.1",
"d3/mailauthenticationcheck": "^0.1.0",
@ -44,20 +44,9 @@
"phpstan/phpstan": "^1.8",
"boxblinkracer/phpunuhi": "^1.12"
},
"extra": {
"oxideshop": {
"blacklist-filter": [
"*.md",
"composer.json",
".php-cs-fixer.php",
"*.neon"
],
"target-directory": "d3/mailconfigchecker"
}
},
"autoload": {
"psr-4": {
"D3\\MailConfigChecker\\": "../../../source/modules/d3/mailconfigchecker"
"D3\\MailConfigChecker\\": ""
}
},
"scripts": {

View File

@ -20,17 +20,17 @@ use D3\MailConfigChecker\Application\Controller\Admin\MailInfoPage;
use D3\MailConfigChecker\Application\Controller\Admin\MailTester;
use D3\MailConfigChecker\Application\Controller\Admin\SpfChecker;
use D3\MailConfigChecker\Application\Controller\Admin\SmtpChecker;
use D3\MailConfigChecker\Application\Model\Constants;
$sMetadataVersion = '2.1';
$sModuleId = 'd3mailconfigchecker';
$logo = '<img src="https://logos.oxidmodule.com/d3logo.svg" alt="(D3)" style="height:1em;width:1em">';
/**
* Module information
*/
$aModule = [
'id' => $sModuleId,
'id' => Constants::OXID_MODULE_ID,
'title' => [
'de' => $logo.' E-Mail Konfigurationspr&uuml;fung',
'en' => $logo.' Mail Configuration Check Tool',
@ -40,7 +40,7 @@ $aModule = [
'en' => '',
],
'thumbnail' => 'picture.svg',
'version' => '2.1.1.0',
'version' => '3.0.1.0',
'author' => 'D&sup3; Data Development (Inh.: Thomas Dartsch)',
'email' => 'support@shopmodule.com',
'url' => 'https://www.oxidmodule.com/',
@ -54,13 +54,13 @@ $aModule = [
'd3mailtester' => MailTester::class,
],
'templates' => [
'mailCheckBase.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/mailcheckbase.tpl',
'mailCheckMenu.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/mailcheckmenu.tpl',
'mailInfoPage.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/mailinfopage.tpl',
'mailConfigCheck.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/mailconfigcheck.tpl',
'smtpCheck.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/smtpCheck.tpl',
'spfCheck.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/spfCheck.tpl',
'mailTester.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/mailTester.tpl',
'inc_bootstrap.tpl' => 'd3/mailconfigchecker/Application/views/admin/tpl/inc/bootstrap.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/mailCheckBase.tpl' => 'views/smarty/admin/mailcheckbase.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/mailCheckMenu.tpl' => 'views/smarty/admin/mailcheckmenu.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/mailInfoPage.tpl' => 'views/smarty/admin/mailinfopage.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/mailConfigCheck.tpl' => 'views/smarty/admin/mailconfigcheck.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/smtpCheck.tpl' => 'views/smarty/admin/smtpCheck.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/spfCheck.tpl' => 'views/smarty/admin/spfCheck.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/mailTester.tpl' => 'views/smarty/admin/mailTester.tpl',
'@' . Constants::OXID_MODULE_ID . '/admin/inc_bootstrap.tpl' => 'views/smarty/admin/inc/bootstrap.tpl',
],
];

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}]
[{include file="inc_bootstrap.tpl"}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
[{if $readonly}]
[{assign var="readonly" value="readonly disabled"}]

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}]
[{include file="inc_bootstrap.tpl"}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
<style>
span.btn {

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}]
[{include file="inc_bootstrap.tpl"}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
<style>
span.btn {

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
[{include file="inc_bootstrap.tpl"}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
<style>
.communicationoutput,

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
[{include file="inc_bootstrap.tpl"}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
<form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post">
[{$oViewConf->getHiddenSid()}]

View File

@ -0,0 +1,14 @@
<link rel="stylesheet" href="{{ oViewConf.getModuleUrl('d3mailconfigchecker', 'out/src/css/bootstrap.min.css') }}">
<style>
* {
font-size: 12px;
box-sizing: initial;
}
a {
color: inherit;
text-decoration: inherit;
}
select {
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>{{ translate({ ident: "GENERAL_ADMIN_TITLE" }) }}</title>
</head>
<!-- frames -->
<frameset rows="10%,*" style="border: none" onload="top.loadEditFrame('{{ oViewConf.getSelfLink()|raw }}&{{ editurl }}{% if oxid %}&oxid={{ oxid }}{% endif %}');">
<frame src="{{ oViewConf.getSelfLink()|raw }}&{{ listurl }}{% if oxid %}&oxid={{ oxid }}{% endif %}" name="list" id="list" style="border: none" frameborder="0" scrolling="Auto" noresize marginwidth="0" marginheight="0">
<frame src="" name="edit" id="edit" style="border: none" frameborder="0" scrolling="Auto" noresize marginwidth="0" marginheight="0">
</frameset>
</html>

View File

@ -0,0 +1,39 @@
{% include "headitem.html.twig" with {title: "GENERAL_ADMIN_TITLE"|translate, box: "list"} %}
{% if readonly %}
{% set readonly = "readonly disabled" %}
{% else %}
{% set readonly = "" %}
{% endif %}
<script type="text/javascript">
<!--
window.onload = function ()
{
{% if updatenav %}
var oTransfer = top.basefrm.edit.document.getElementById( "transfer" );
oTransfer.updatenav.value = 1;
oTransfer.cl.value = '{{ default_edit }}';
{% endif %}
top.reloadEditFrame();
}
//-->
</script>
<form name="search" id="search" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{% include "_formparams.html.twig" with {cl: oViewConf.getActiveClassName()|raw, lstrt: lstrt, actedit: actedit, oxid: oxid, fnc: "", language: actlang, editlanguage: actlang} %}
</form>
{% include "pagetabsnippet.html.twig" %}
<script type="text/javascript">
if (parent.parent != null && parent.parent.setTitle )
{ parent.parent.sShopTitle = "{{ actshopobj.oxshops__oxname.getRawValue()|addslashes }}";
parent.parent.sMenuItem = "{{ translate({ ident: "SHOP_LIST_MENUITEM" }) }}";
parent.parent.sMenuSubItem = "{{ translate({ ident: "SHOP_LIST_MENUSUBITEM" }) }}";
parent.parent.sWorkArea = "{{ _act }}";
parent.parent.setTitle();
}
</script>
</body>
</html>

View File

@ -0,0 +1,80 @@
{% include "headitem.html.twig" with {title: "d3mxd3cleartmp"|translate} %}
{% include "@d3mailconfigchecker/admin/inc/bootstrap.html.twig" %}
<style>
span.btn {
cursor: default;
}
.communicationoutput {
background-color: black;
color: white;
max-height: 500px;
overflow: auto;
margin-top: 30px;
}
</style>
{% set readonly = "readonly disabled" %}
<form name="transfer" id="transfer" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="oxid" value="{{ oxid }}">
<input type="hidden" name="oxidCopy" value="{{ oxid }}">
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
</form>
<div class="row">
<div class="col-12 col-md-6 col-lg-4 mb-4">
<div>
<label class="col-4 form-label" for="oxshops__oxsmtp">{{ translate({ ident: "SHOP_MAIN_SMTPSERVER" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxsmtp.fldmax_length }}" id="oxshops__oxsmtp" value="{{ shop.getFieldData('oxsmtp') }}" {{ readonly }}>
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxsmtpuser">{{ translate({ ident: "SHOP_MAIN_SMTPUSER" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxsmtpuser.fldmax_length }}" id="oxshops__oxsmtpuser" value="{{ shop.getFieldData('oxsmtpuser') }}" {{ readonly }}>
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxinfoemail">{{ translate({ ident: "SHOP_MAIN_INFOEMAIL" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxinfoemail.fldmax_length }}" id="oxshops__oxinfoemail" value="{{ shop.getFieldData('oxinfoemail') }}" {{ readonly }}>
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxorderemail">{{ translate({ ident: "SHOP_MAIN_ORDEREMAIL" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxorderemail.fldmax_length }}" id="oxshops__oxorderemail" value="{{ shop.getFieldData('oxorderemail') }}" {{ readonly }}>
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxowneremail">{{ translate({ ident: "SHOP_MAIN_OWNEREMAIL" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxowneremail.fldmax_length }}" id="oxshops__oxowneremail" value="{{ shop.getFieldData('oxowneremail') }}" {{ readonly }}>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4">
{% if mailer %}
<div>
{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_SHOPSEND", suffix: "COLON" }) }}
{% if mailer == 'mail' %}
<button type="button" class="btn btn-danger">{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER" }) }}</button><br>
{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER_DESC" }) }}
{% else %}
<span class="btn btn-success">{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP" }) }}</span><br>
{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC" }) }}
{% endif %}
</div>
<div class="col-12 communicationoutput">
{{ communication|raw }}
</div>
{% else %}
<form name="myedit" id="myedit" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="fnc" value="checkConfiguration">
<input type="hidden" name="recipient" value="{{ recipient }}">
<button type="submit" class="btn btn-primary">{{ translate({ ident: "D3_MAILCHECKER_CFGCHECK_STARTCHECK" }) }}</button>
</form>
{% endif %}
</div>
</div>
{% include "bottomnaviitem.html.twig" %}
{% include "bottomitem.html.twig" %}

View File

@ -0,0 +1,34 @@
{% include "headitem.html.twig" with {title: "d3mxd3cleartmp"|translate} %}
{% include "@d3mailconfigchecker/admin/inc/bootstrap.html.twig" %}
<style>
span.btn {
cursor: default;
}
</style>
{% set readonly = "readonly disabled" %}
<form name="transfer" id="transfer" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="oxid" value="{{ oxid }}">
<input type="hidden" name="oxidCopy" value="{{ oxid }}">
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
</form>
<div class="row">
<div class="col-12 col-md-10 col-lg-8 mb-4">
<p>
{{ translate({ ident: "D3_MAILCHECKER_INFO_1" }) }}
</p>
<p>
{{ translate({ ident: "D3_MAILCHECKER_INFO_2" }) }}
</p>
<p>
{{ translate({ ident: "D3_MAILCHECKER_INFO_3" }) }}
</p>
</div>
</div>
{% include "bottomnaviitem.html.twig" %}
{% include "bottomitem.html.twig" %}

View File

@ -0,0 +1,71 @@
{% include "headitem.html.twig" with {title: "d3mxd3cleartmp"|translate} %}
{% include "@d3mailconfigchecker/admin/inc/bootstrap.html.twig" %}
{% if readonly %}
{% set readonly = "readonly disabled" %}
{% else %}
{% set readonly = "" %}
{% endif %}
<form name="transfer" id="transfer" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="oxid" value="{{ oxid }}">
<input type="hidden" name="oxidCopy" value="{{ oxid }}">
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
</form>
{% if success %}
<div class="alert alert-success">{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_SUCCESS" }) }}</div>
{% endif %}
<div class="col-12 col-md-10 col-lg-8 mb-4">
{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_DESC" }) }}
</div>
<h5>{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_LINKS" }) }}</h5>
<ul>
<li>
<a href="https://mxtoolbox.com/EmailHeaders.aspx">
{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_HEADERANALYSIS" }) }}
</a>
</li>
</ul>
<div class="row">
<div class="col-12 col-md-6 col-lg-4 mb-4">
<form name="myedit" id="myedit" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="fnc" value="sendMail">
<div>
<label class="col-4 form-label" for="sender">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_SENDER" }) }}</label>
<select name="from" class="col-7 editinput" id="sender">
{% for address in oView.getMailAddressList() %}
<option value="{{ address }}" {% if sender == address %}selected{% endif %}>{{ address }}</option>
{% endfor %}
</select>
</div>
<div>
<label class="col-4 form-label" for="recipient">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_RECIPIENT" }) }}</label>
<input name="to" type="text" class="col-7 editinput" size="35" maxlength="255" id="recipient" value="{{ recipient }}">
</div>
<div>
<label class="col-4 form-label" for="subject">{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_SUBJECT" }) }}</label>
<input type="text" class="col-7 editinput" id="subject" maxlength="255" name="subject" value="{{ subject }}">
</div>
<div>
<label class="col-4 form-label" for="body">{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_BODY" }) }}</label>
<textarea name="body" class="col-7 editinput" id="body" maxlength="255" style="height: 100px">{% apply spaceless %}
{{ body }}
{% endapply %}</textarea>
</div>
<div>
<button type="submit" class="btn btn-primary offset-4">{{ translate({ ident: "D3_MAILCHECKER_TESTMAIL_SENDMAIL" }) }}</button>
</div>
</form>
</div>
</div>
{% include "bottomnaviitem.html.twig" %}
{% include "bottomitem.html.twig" %}

View File

@ -0,0 +1,96 @@
{% include "headitem.html.twig" with {title: "GENERAL_ADMIN_TITLE"|translate} %}
{% include "@d3mailconfigchecker/admin/inc/bootstrap.html.twig" %}
<style>
.communicationoutput,
.communicationoutput dl dt,
.communicationoutput dl dd {
background-color: black;
color: white;
}
</style>
<form name="transfer" id="transfer" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="oxid" value="{{ oxid }}">
<input type="hidden" name="oxidCopy" value="{{ oxid }}">
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="editlanguage" value="{{ editlanguage }}">
</form>
{% if success %}
<div class="alert alert-success">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_SUCCESS" }) }}</div>
{% endif %}
<div class="row">
<div class="col-12 col-md-6 col-lg-4 mb-4">
<p>
{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_DESC1" }) }}
</p>
<p>
{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_DESC2" }) }}
</p>
<p>
{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_DESC3" }) }}
</p>
<form name="myedit" id="myedit" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="fnc" value="sendMail">
<div>
<label class="col-4 form-label" for="oxshops__oxsmtp">{{ translate({ ident: "SHOP_MAIN_SMTPSERVER" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxsmtp.fldmax_length }}" id="oxshops__oxsmtp" name="smtpHost" value="{% if smtpHost %}{{ smtpHost }}{% else %}{{ shop.getFieldData('oxsmtp') }}{% endif %}">
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxsmtpuser">{{ translate({ ident: "SHOP_MAIN_SMTPUSER" }) }}</label>
<input type="text" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxsmtpuser.fldmax_length }}" id="oxshops__oxsmtpuser" name="smtpUser" value="{% if smtpUser %}{{ smtpUser }}{% else %}{{ shop.getFieldData('oxsmtpuser') }}{% endif %}">
</div>
<div>
<label class="col-4 form-label" for="oxshops__oxsmtppwd">{{ translate({ ident: "SHOP_MAIN_SMTPPASSWORD" }) }}</label>
<input type="password" class="col-7 editinput" size="35" maxlength="{{ shop.oxshops__oxsmtppwd.fldmax_length }}" id="oxshops__oxsmtppwd" name="smtpPwd" value="{% if smtpPwd %}{{ smtpPwd }}{% else %}{{ shop.getFieldData('oxsmtppwd') }}{% endif %}">
</div>
<div>
<label class="col-4 form-label" for="sender">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_SENDER" }) }}</label>
<select name="from" class="col-7 editinput" id="sender">
{% for address in oView.getMailAddressList() %}
<option value="{{ address }}">{{ address }}</option>
{% endfor %}
</select>
</div>
<div>
<label class="col-4 form-label" for="recipient">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_RECIPIENT" }) }}</label>
<input name="to" type="text" class="col-7 editinput" size="35" maxlength="255" id="recipient" value="{{ recipient }}">
</div>
<div>
<label class="col-4 form-label" for="sendmail">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_TESTSENDMAIL" }) }}</label>
<input type="checkbox" class="col-7 editinput" id="sendmail" name="sendmail" value="1" {% if sendMail %}checked{% endif %}>
</div>
<div>
<button type="submit" class="btn btn-primary offset-4">{{ translate({ ident: "D3_MAILCHECKER_SMTPCHECK_STARTTEST" }) }}</button>
</div>
</form>
</div>
<div class="col-12 col-md-6 col-lg-4 mb-4 {% if smtpLog %}communicationoutput{% endif %}">
{% for action, logItems in smtpLog %}
<dl>
<dt>{{ loop.index }} - {{ action }}</dt>
<dd>
<ul>
{% for logItem in logItems %}
<li>
{{ logItem }}
</li>
{% endfor %}
</ul>
</dd>
</dl>
{% endfor %}
</div>
</div>
{% include "bottomnaviitem.html.twig" %}
{% include "bottomitem.html.twig" %}

View File

@ -0,0 +1,112 @@
{% include "headitem.html.twig" with {title: "GENERAL_ADMIN_TITLE"|translate} %}
{% include "@d3mailconfigchecker/admin/inc/bootstrap.html.twig" %}
<form name="transfer" id="transfer" action="{{ oViewConf.getSelfLink()|raw }}" method="post">
{{ oViewConf.getHiddenSid()|raw }}
<input type="hidden" name="oxid" value="{{ oxid }}">
<input type="hidden" name="oxidCopy" value="{{ oxid }}">
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
<input type="hidden" name="editlanguage" value="{{ editlanguage }}">
</form>
<div class="row">
<div class="col-12 mb-4">
<h4>{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_HL" }) }}</h4>
{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_DESC" }) }}
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<div class="row">
{% for domain, spf in spf_result %}
<div class="col-12 col-md-6 col-lg-3">
<div class="card mb-3">
<div class="card-header text-white bg-{{ oView.getSpfStatusColor(spf) }}">
{{ domain }}
</div>
<div class="card-body">
<p>{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_"|cat(spf.getStatus())|upper }) }}</p>
{% if spf.getRecord() %}
<p>
<label for="{{ domain }}_record">{{ translate({ ident: "D3_MAILCHECKER_RECORD", suffix: "COLON" }) }}</label>
<input type="text" id="{{ domain }}_record" value="{{ spf.getRecord() }}" style="width: 50%;" readonly disabled>
</p>
{% endif %}
<h5>{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_LINKS" }) }}</h5>
<ul>
{% if spf.getRecord() %}
<li>
<a href="https://mxtoolbox.com/SuperTool.aspx?action=spf%3a{{ domain }}&run=toolpage">
{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_LINK_ANALYSIS" }) }}
</a>
</li>
{% else %}
<li>
<a href="https://mxtoolbox.com/SPFRecordGenerator.aspx?domain={{ domain }}&prefill=true">
{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR" }) }}
</a>
</li>
{% endif %}
<li>
<a href="https://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a{{ domain }}&run=toolpage">
{{ translate({ ident: "D3_MAILCHECKER_SPFRESULT_LINK_BLACKLISTCHECK" }) }}
</a>
</li>
</ul>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<h4>{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_HL" }) }}</h4>
{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_DESC" }) }}
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<div class="row">
{% for domain, dmarc in dmarc_result %}
<div class="col-12 col-md-6 col-lg-3">
<div class="card mb-3">
<div class="card-header text-white bg-{{ oView.getDmarcStatusColor(dmarc) }}">
{{ domain }}
</div>
<div class="card-body">
<p>{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_"|cat(dmarc.getStatus())|upper }) }}</p>
{% if dmarc.getRecord() %}
<p>
<label for="{{ domain }}_record">{{ translate({ ident: "D3_MAILCHECKER_RECORD", suffix: "COLON" }) }}</label>
<input type="text" id="{{ domain }}_record" value="{{ dmarc.getRecord() }}" style="width: 50%;" readonly disabled>
</p>
{% endif %}
<h5>{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_LINKS" }) }}</h5>
<ul>
<li>
<a href="https://mxtoolbox.com/SuperTool.aspx?action=dmarc%3a{{ domain }}&run=toolpage">
{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS" }) }}
</a>
</li>
<li>
<a href="https://mxtoolbox.com/DMARCRecordGenerator.aspx?domain={{ domain }}&prefill=true">
{{ translate({ ident: "D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR" }) }}
</a>
</li>
</ul>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% include "bottomnaviitem.html.twig" %}
{% include "bottomitem.html.twig" %}