Compare commits

..

7 Commits

43 changed files with 218 additions and 965 deletions

View File

@ -1,13 +1,17 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* 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.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link https://www.oxidmodule.com
*/
@ -15,12 +19,11 @@ 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 = '@'.Constants::OXID_MODULE_ID.'/admin/mailCheckBase';
protected $_sThisTemplate = 'mailCheckBase.tpl';
/**
* @return string

View File

@ -1,13 +1,17 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
* 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.
*
* https://www.d3data.de
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link https://www.oxidmodule.com
*/
@ -15,14 +19,13 @@ 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 = '@'.Constants::OXID_MODULE_ID.'/admin/mailCheckMenu';
protected $_sThisTemplate = 'mailCheckMenu.tpl';
public function render(): string
public function render()
{
$this->setEditObjectId('foo');
return parent::render();

View File

@ -1,22 +1,24 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
* 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
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://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 ErrorException;
use Exception;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Application\Model\Shop;
@ -25,19 +27,18 @@ use OxidEsales\Eshop\Core\Registry;
class MailConfigCheck extends AdminDetailsController
{
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailConfigCheck';
protected string $testMailAddress = 'test@example.com';
protected $_sThisTemplate = 'mailConfigCheck.tpl';
protected $testMailAddress = 'test@example.com';
public function render(): string
public function render()
{
$this->checkDataAreSet();
$this->addTplParam('shop', Registry::getConfig()->getActiveShop());
$this->addTplParam('recipient', $this->testMailAddress);
return parent::render();
}
protected function checkDataAreSet(): void
protected function checkDataAreSet()
{
try {
/** @var Shop $shop */
@ -65,42 +66,31 @@ class MailConfigCheck extends AdminDetailsController
}
}
public function checkConfiguration(): void
public function checkConfiguration()
{
$this->getCurrentMailer();
}
protected function getCurrentMailer(): void
function exceptions_error_handler($severity, $message, $filename, $lineno) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
protected function getCurrentMailer()
{
try {
$shop = Registry::getConfig()->getActiveShop();
$config = Registry::getConfig();
$mail = oxNew(Email::class);
$mail->setRecipient(
trim(Registry::getRequest()->getRequestEscapedParameter('recipient')) ?: $this->testMailAddress
);
$mail->setRecipient($this->testMailAddress);
$mail->setBody('.');
$mail->setFrom($shop->getFieldData('oxowneremail'));
$currentDebug = $config->getConfigParam('iDebug');
$config->setConfigParam('iDebug', 6);
$mail->setSmtp();
ob_start();
set_error_handler([$this, 'exceptions_error_handler']);
$mail->send();
$communication = ob_get_contents();
ob_end_clean();
$re = '/(^|\<br\>)(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s)/m';
$subst = "$1";
$communication = preg_replace($re, $subst, $communication);
$config->setConfigParam('iDebug', $currentDebug);
$this->addTplParam('mailer', $mail->getMailer());
$this->addTplParam('communication', $communication);
} catch (Exception $e) {
Registry::getUtilsView()->addErrorToDisplay($e);
} finally {
restore_error_handler();
}
}
}

View File

@ -1,22 +1,23 @@
<?php
/**
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* https://www.d3data.de
* 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
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://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 = '@'.Constants::OXID_MODULE_ID.'/admin/mailInfoPage';
protected $_sThisTemplate = 'mailInfoPage.tpl';
}

View File

@ -1,22 +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
* 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
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <info@shopmodule.com>
* @link https://www.oxidmodule.com
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://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 = '@'.Constants::OXID_MODULE_ID.'/admin/mailTester';
protected $_sThisTemplate = 'mailTester.tpl';
public function sendMail(): void
public function sendMail()
{
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(): void
protected function assertContent()
{
$request = Registry::getRequest();
$lang = Registry::getLang();
@ -77,7 +77,7 @@ class MailTester extends AdminDetailsController
->verifyNow();
}
public function getMailAddressList(): array
public function getMailAddressList()
{
/** @var Shop $shop */
$shop = Registry::getConfig()->getActiveShop();

View File

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

View File

@ -16,15 +16,8 @@ declare(strict_types=1);
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;
use Mika56\SPFCheck\DNSRecordGetter;
use Mika56\SPFCheck\SPFCheck;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Application\Model\Shop;
@ -32,16 +25,15 @@ use OxidEsales\Eshop\Core\Registry;
class SpfChecker extends AdminDetailsController
{
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/spfCheck';
protected $_sThisTemplate = 'spfCheck.tpl';
public function render(): ?string
public function render()
{
$this->checkSpf();
$this->checkDmarc();
return parent::render();
}
protected function checkSpf(): void
protected function checkSpf()
{
$result = [];
$mailDomains = $this->getMailDomains();
@ -52,24 +44,10 @@ class SpfChecker extends AdminDetailsController
}
);
$this->addTplParam('spf_result', $result);
$this->addTplParam('result', $result);
}
protected function checkDmarc(): void
{
$result = [];
$mailDomains = $this->getMailDomains();
array_walk(
$mailDomains,
function ($domain) use (&$result) {
$this->checkDmarcByDomain($domain, $result);
}
);
$this->addTplParam('dmarc_result', $result);
}
protected function getMailDomains(): array
protected function getMailDomains()
{
/** @var Shop $shop */
$shop = Registry::getConfig()->getActiveShop();
@ -81,13 +59,13 @@ class SpfChecker extends AdminDetailsController
function ($mailAddress) {
$mailAddress = trim($mailAddress);
try {
if ( ! str_contains( $mailAddress, '@' ) ) {
if (! strstr($mailAddress, '@')) {
throw oxNew(InvalidArgumentException::class);
}
$addressChunks = explode('@', $mailAddress);
return array_pop($addressChunks);
} catch (InvalidArgumentException) {
} catch (InvalidArgumentException $e) {
return '';
}
},
@ -101,59 +79,40 @@ class SpfChecker extends AdminDetailsController
);
}
protected function checkSpfByDomain($domain, &$summarize): void
protected function checkSpfByDomain($domain, &$summarize)
{
$checker = new SPFCheck(new DNSRecordGetter());
$query = new Query('', $domain);
$result = $checker->getResult($query);
$status = match ( $result->getResult() ) {
Result::FAIL, Result::NEUTRAL, Result::PASS, Result::SOFTFAIL => SpfResult::SET,
Result::NONE => SpfResult::MISSING,
default => SpfResult::ERROR,
};
switch ($checker->isIPAllowed(gethostbyname($domain), $domain)) {
case SPFCheck::RESULT_FAIL:
case SPFCheck::RESULT_NEUTRAL:
case SPFCheck::RESULT_PASS:
case SPFCheck::RESULT_SOFTFAIL:
$status = SpfResult::SET;
break;
case SPFCheck::RESULT_NONE:
$status = SpfResult::MISSING;
break;
default:
$status = SpfResult::ERROR;
}
$rawRecord = ($record = $result->getRecord()) ?
$record->getRawRecord() :
$rawRecord = ($record = (new DNSRecordGetter())->getSPFRecordForDomain($domain)) ?
implode(', ', $record) :
null;
$summarize[$domain] = oxNew(SpfResult::class, $status, $rawRecord);
}
public function getSpfStatusColor(SpfResult $result): string
public function getSpfStatusColor(SpfResult $result)
{
return match ( $result->getStatus() ) {
SpfResult::SET => 'success',
SpfResult::ERROR => 'warning',
default => 'danger',
};
}
public function checkDmarcByDomain($domain, &$summarize): void
{
try {
$check = new DMARCCheck(new DNSRecordGetter());
$query = new Query('', $domain);
$record = $check->getResult($query)->getRecord();
$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) {
$summarize[$domain] = oxNew( OxDmarcResult::class, OxDmarcResult::MISSING, '');
switch ($result->getStatus()) {
case SpfResult::SET:
return 'success';
case SpfResult::ERROR:
return 'warning';
default:
return 'danger';
}
}
public function getDmarcStatusColor(OxDmarcResult $result): string
{
return match ( $result->getStatus() ) {
SpfResult::SET => 'success',
SpfResult::ERROR => 'warning',
default => 'danger',
};
}
}

View File

@ -1,21 +0,0 @@
<?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

@ -1,42 +0,0 @@
<?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 DmarcResult
{
public const SET = 'set';
public const MISSING = 'missing';
public const ERROR = 'error';
protected $status;
protected $record;
public function __construct(string $status, ?string $record = null)
{
$this->status = $status;
$this->record = $record;
}
public function getStatus(): string
{
return $this->status;
}
public function getRecord(): ?string
{
return $this->record;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,18 +1,10 @@
[{include file="headitem.tpl" title="d3mxd3cleartmp"|oxmultilangassign}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
[{include file="inc_bootstrap.tpl"}]
<style>
span.btn {
cursor: default;
}
.communicationoutput {
background-color: black;
color: white;
max-height: 500px;
overflow: auto;
margin-top: 30px;
}
</style>
[{assign var="readonly" value="readonly disabled"}]
@ -60,16 +52,11 @@
[{oxmultilang ident="D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC"}]
[{/if}]
</div>
<div class="col-12 communicationoutput">
[{$communication}]
</div>
[{else}]
<form name="myedit" id="myedit" action="[{$oViewConf->getSelfLink()}]" method="post">
[{$oViewConf->getHiddenSid()}]
<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">[{oxmultilang ident="D3_MAILCHECKER_CFGCHECK_STARTCHECK"}]</button>
</form>
[{/if}]

View File

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

View File

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

View File

@ -1,5 +1,5 @@
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
[{include file="@d3mailconfigchecker/admin/inc_bootstrap.tpl"}]
[{include file="inc_bootstrap.tpl"}]
<form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post">
[{$oViewConf->getHiddenSid()}]
@ -10,16 +10,15 @@
</form>
<div class="row">
<div class="col-12 mb-4">
<h4>[{oxmultilang ident="D3_MAILCHECKER_SPFRESULT_HL"}]</h4>
<div class="col-12 col-md-10 col-lg-8 mb-4">
[{oxmultilang ident="D3_MAILCHECKER_SPFRESULT_DESC"}]
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<div class="col-12 col-md-10 col-lg-8 mb-4">
<div class="row">
[{foreach from=$spf_result key="domain" item="spf"}]
<div class="col-12 col-md-6 col-lg-3">
[{foreach from=$result key="domain" item="spf"}]
<div class="col-12 col-md-6 col-lg-4">
<div class="card mb-3">
<div class="card-header text-white bg-[{$oView->getSpfStatusColor($spf)}]">
[{$domain}]
@ -28,8 +27,8 @@
<p>[{oxmultilang ident="D3_MAILCHECKER_SPFRESULT_"|cat:$spf->getStatus()|upper}]</p>
[{if $spf->getRecord()}]
<p>
<label for="[{$domain}]_record">[{oxmultilang ident="D3_MAILCHECKER_RECORD" suffix="COLON"}]</label>
<input type="text" id="[{$domain}]_record" value="[{$spf->getRecord()}]" style="width: 50%;" readonly disabled>
<label for="[{$domain}]_record">Eintrag:</label>
<input type="text" id="[{$domain}]_record" value="[{$spf->getRecord()}]" readonly disabled>
</p>
[{/if}]
@ -46,6 +45,7 @@
<a href="https://mxtoolbox.com/SPFRecordGenerator.aspx?domain=[{$domain}]&prefill=true">
[{oxmultilang ident="D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR"}]
</a>
</li>
[{/if}]
<li>
@ -62,51 +62,6 @@
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<h4>[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_HL"}]</h4>
[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_DESC"}]
</div>
</div>
<div class="row">
<div class="col-12 mb-4">
<div class="row">
[{foreach from=$dmarc_result key="domain" item="dmarc"}]
<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>[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_"|cat:$dmarc->getStatus()|upper}]</p>
[{if $dmarc->getRecord()}]
<p>
<label for="[{$domain}]_record">[{oxmultilang ident="D3_MAILCHECKER_RECORD" suffix="COLON"}]</label>
<input type="text" id="[{$domain}]_record" value="[{$dmarc->getRecord()}]" style="width: 50%;" readonly disabled>
</p>
[{/if}]
<h5>[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_LINKS"}]</h5>
<ul>
<li>
<a href="https://mxtoolbox.com/SuperTool.aspx?action=dmarc%3a[{$domain}]&run=toolpage">
[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS"}]
</a>
</li>
<li>
<a href="https://mxtoolbox.com/DMARCRecordGenerator.aspx?domain=[{$domain}]&prefill=true">
[{oxmultilang ident="D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR"}]
</a>
</li>
</ul>
</div>
</div>
</div>
[{/foreach}]
</div>
</div>
</div>
[{include file="bottomnaviitem.tpl"}]
[{include file="bottomitem.tpl"}]

View File

@ -1,22 +0,0 @@
<?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

@ -1,22 +0,0 @@
<?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,22 +0,0 @@
<?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

@ -1,22 +0,0 @@
<?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,25 +1,12 @@
<?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',
'D3_TAB_MAILCHECKER_MODULEDESCRIPTION' => 'Beschreibung',
'D3_TAB_MAILCHECKER_CONFIGCHECK' => 'Konfigurationsprüfung',
'D3_TAB_MAILCHECKER_SMTPCHECK' => 'SMTP Check',
'D3_TAB_MAILCHECKER_SPFCHECK' => 'Authentisierung Check',
'D3_TAB_MAILCHECKER_SPFCHECK' => 'SPF Check',
'D3_TAB_MAILCHECKER_TESTMAIL' => 'Testmail',
'D3_MAILCHECKER_INFO_1' => 'Dieses Modul kann Ihnen helfen, um Schwierigkeiten beim Versand von Mails oder bei nicht zugestellten Mails zu identifizieren. Gehen Sie bitte die folgenden Tabs durch. Nötige Nacharbeiten werden Ihnen dort angezeigt.',
@ -33,7 +20,7 @@ return [
'D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER' => 'PhpMailer',
'D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER_DESC' => 'Der Versand über den PhpMailer sollte dringend vermieden werden, da solche Mails meist als Spam eingestuft werden. Wenn Sie alle SMTP-Daten eingegeben haben, prüfen Sie mögliche Anmeldeprobleme im SMTP-Check.',
'D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP' => 'SMTP',
'D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC' => 'Alles in bester Ordnung. Bitte prüfen Sie noch die nötigen Einstellungen im Tab "Authorisierung Check" für Ihre Domain(s).',
'D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC' => 'Alles in bester Ordnung. Bitte prüfen Sie noch die nötigen SPF-Einträge für Ihre Domain(s).',
'D3_MAILCHECKER_CFGCHECK_STARTCHECK' => 'Konfiguration testen',
'D3_MAILCHECKER_SMTPCHECK_DESC1' => 'Wenn trotz passend eingegebenen Daten kein Mailversand über SMTP erfolgt, kann hier der Anmeldeversuch am Postausgangsserver nachvollzogen werden. Eventuell auftretende Meldungen werden gezeigt.',
@ -54,9 +41,6 @@ return [
'D3_MAILCHECKER_SMTPCHECK_NOTRANSMIT' => 'Datenübertragung nicht erfolgreich',
'D3_MAILCHECKER_SMTPCHECK_SUCCESS' => 'Die SMTP-Kommunikation wurde erfolgreich abgeschlossen.',
'D3_MAILCHECKER_RECORD' => 'Eintrag',
'D3_MAILCHECKER_SPFRESULT_HL' => 'SPF (Herkunftsprüfung)',
'D3_MAILCHECKER_SPFRESULT_DESC' => 'Mit dem Sender Policy Framework (SPF) definiert der Domaininhaber, welcher Server E-Mails mit dem Domainabsender versenden darf. Diese Angabe wird vom Empfangsserver geprüft. Fehlt der SPF-Eintrag, werden E-Mails üblicherweise als Spam klassifiziert.',
'D3_MAILCHECKER_SPFRESULT_SET' => 'Es ist ein SPF-Eintrag gesetzt',
'D3_MAILCHECKER_SPFRESULT_MISSING' => 'Es ist kein SPF-Eintrag gesetzt, dieser sollte dringend nachgetragen werden',
@ -66,15 +50,6 @@ return [
'D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR' => 'SPF Generator',
'D3_MAILCHECKER_SPFRESULT_LINK_BLACKLISTCHECK' => 'Blacklist Check',
'D3_MAILCHECKER_DMARCRESULT_HL' => 'DMARC (Ablehnungsrichtlinien und Berichterstattung)',
'D3_MAILCHECKER_DMARCRESULT_DESC' => 'Der DMARC-Eintrag definiert, wie mit Mails umgegangen wird, bei denen die Authentisierungsprüfungen fehlgeschlagen sind. Dort können auch Mailadressen für Reporte angegeben werden.',
'D3_MAILCHECKER_DMARCRESULT_SET' => 'Es ist ein DMARC-Eintrag gesetzt, das Verhalten ist nicht auf "ignorieren" gestellt.',
'D3_MAILCHECKER_DMARCRESULT_MISSING' => 'Es ist kein DMARC-Eintrag gesetzt oder mit "ignorieren" konfiguriert. Dies sollte dringend geändert werden.',
'D3_MAILCHECKER_DMARCRESULT_ERROR' => 'Der DMARC-Eintrag kann nicht geprüft werden',
'D3_MAILCHECKER_DMARCRESULT_LINKS' => 'weiterführende Links',
'D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS' => 'DMARC Analyse',
'D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR' => 'DMARC Generator',
'D3_MAILCHECKER_TESTMAIL_DESC' => 'Die Testmail wird auf identischem Weg geschickt, den auch alle regulären Mails aus dem Shop nehmen (z.B. Bestellbestätigungen, ...) und kann z.B. zur Headeranalyse dienen.',
'D3_MAILCHECKER_TESTMAIL_HEADERANALYSIS' => 'Email Header Analyzer',
'D3_MAILCHECKER_TESTMAIL_SUBJECT' => 'Betreff',

View File

@ -1,25 +1,12 @@
<?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",
"D3_TAB_MAILCHECKER_MODULEDESCRIPTION" => "Description",
"D3_TAB_MAILCHECKER_CONFIGCHECK" => "Configuration check",
"D3_TAB_MAILCHECKER_SMTPCHECK" => "SMTP check",
"D3_TAB_MAILCHECKER_SPFCHECK" => "Authentication check",
"D3_TAB_MAILCHECKER_SPFCHECK" => "SPF check",
"D3_TAB_MAILCHECKER_TESTMAIL" => "Test email",
"D3_MAILCHECKER_ASSERTIONS_FAILED" => "The following %d checks failed:",
"D3_MAILCHECKER_ASSERTIONS_NOTSET" => "is not (correctly) set",
@ -28,7 +15,7 @@ return [
"D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER" => "PhpMailer",
"D3_MAILCHECKER_CFGCHECK_SHOPSEND_PHPMAILER_DESC" => "Sending via PhpMailer should be avoided as such emails are usually classified as spam. Once you have entered all SMTP data, check possible login problems in the SMTP check.",
"D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP" => "SMTP",
"D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC" => "Everything is fine. Please check the necessary settings for your domain(s) in the \"Authentication Check\" tab .",
"D3_MAILCHECKER_CFGCHECK_SHOPSEND_SMTP_DESC" => "Everything is fine. Please check the necessary SPF entries for your domain(s).",
"D3_MAILCHECKER_CFGCHECK_STARTCHECK" => "Test configuration",
"D3_MAILCHECKER_SMTPCHECK_DESC1" => "If no mail is sent via SMTP despite the appropriate data entered, the attempt to log in to the outgoing mail server can be repeated here. Any messages that may occur are shown.",
"D3_MAILCHECKER_SMTPCHECK_DESC2" => "New connections can also be tested here in advance.",
@ -47,10 +34,6 @@ return [
"D3_MAILCHECKER_SMTPCHECK_TRANSMIT" => "Data transfer",
"D3_MAILCHECKER_SMTPCHECK_NOTRANSMIT" => "Data transfer not successful",
"D3_MAILCHECKER_SMTPCHECK_SUCCESS" => "SMTP communication was completed successfully.",
'D3_MAILCHECKER_RECORD' => 'Record',
'D3_MAILCHECKER_SPFRESULT_HL' => 'SPF (Origin verification)',
"D3_MAILCHECKER_SPFRESULT_DESC" => "With the Sender Policy Framework (SPF), the domain owner defines which server is allowed to send emails with the domain sender. This information is checked by the receiving server. If the SPF entry is missing, emails are usually sent as ",
"D3_MAILCHECKER_SPFRESULT_SET" => "An SPF entry is set",
"D3_MAILCHECKER_SPFRESULT_MISSING" => "There is no SPF entry set, this should be added urgently",
@ -59,16 +42,6 @@ return [
"D3_MAILCHECKER_SPFRESULT_LINK_ANALYSIS" => "SPF analysis",
"D3_MAILCHECKER_SPFRESULT_LINK_GENERATOR" => "SPF generator",
"D3_MAILCHECKER_SPFRESULT_LINK_BLACKLISTCHECK" => "Blacklist check",
'D3_MAILCHECKER_DMARCRESULT_HL' => 'DMARC (Reject policy and reporting)',
'D3_MAILCHECKER_DMARCRESULT_DESC' => 'The DMARC entry defines how to deal with mails for which the authentication checks have failed. Mail addresses for reports can also be specified there.',
'D3_MAILCHECKER_DMARCRESULT_SET' => 'A DMARC entry is set, the behaviour is not set to ignore.',
'D3_MAILCHECKER_DMARCRESULT_MISSING' => 'No DMARC entry is set or configured with ignore. This should be changed urgently.',
'D3_MAILCHECKER_DMARCRESULT_ERROR' => 'The DMARC record cannot be checked',
'D3_MAILCHECKER_DMARCRESULT_LINKS' => 'Related Links',
'D3_MAILCHECKER_DMARCRESULT_LINK_ANALYSIS' => 'DMARC analysis',
'D3_MAILCHECKER_DMARCRESULT_LINK_GENERATOR' => 'DMARC generator',
"D3_MAILCHECKER_TESTMAIL_DESC" => "The test email is sent in the same way as all regular emails from the shop (e.g..B. order confirmations, ...) and can ",
"D3_MAILCHECKER_TESTMAIL_HEADERANALYSIS" => "Email Header Analyzer",
"D3_MAILCHECKER_TESTMAIL_SUBJECT" => "Regarding",

View File

@ -4,41 +4,13 @@ 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/3.0.1.0...rel_3.x)
## [Unreleased](https://git.d3data.de/D3Public/MyModule/compare/1.0.0.0...rel_1.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
- 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
## [2.1.0.0](https://git.d3data.de/D3Public/MailConfigChecker/compare/2.0.0.1...2.1.0.0) - 2024-06-05
### Added
- check for DMARC DNS record
## [2.0.0.1](https://git.d3data.de/D3Public/MailConfigChecker/compare/2.0.0.0...2.0.0.1) - 2024-04-11
## [1.0.0.1](https://git.d3data.de/D3Public/MailConfigChecker/releases/tag/1.0.0.1) - 2024-04-11
### Fixed
- MailConfigCheck need a valid "from" mailadress to check smtp correctly
## [2.0.0.0](https://git.d3data.de/D3Public/MailConfigChecker/releases/tag/2.0.0.0) - 2023-12-13
## [1.0.0.0](https://git.d3data.de/D3Public/MailConfigChecker/releases/tag/1.0.0.0) - 2023-12-13
### Added
- Checking the mail configuration
- Checking the transmission path used

View File

@ -18,7 +18,7 @@ This package requires an OXID eShop installed with Composer in a version defined
Open a command line and navigate to the root directory of the shop (parent directory of source and vendor). Execute the following commands. Adapt the path details to your installation environment.
```bash
composer require d3/mailconfigchecker:^2.0
composer require d3/mailconfigchecker:^1.0
```
Activate the module in Shopadmin under "Extensions -> Modules".

View File

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

View File

@ -12,7 +12,6 @@
"SMTP",
"phpMailer",
"SPF",
"DMARC",
"testing"
],
"authors": [
@ -31,22 +30,26 @@
"GPL-3.0-or-later"
],
"require": {
"php": "^8",
"oxid-esales/oxideshop-ce": "7.0 - 7.1",
"php": ">=7.1",
"oxid-esales/oxideshop-ce": "6.3 - 6.9",
"pear/net_smtp": "^1.11",
"mika56/spfcheck": "^2.1.1",
"d3/mailauthenticationcheck": "^0.1.0",
"mika56/spfcheck": "^1.1.7",
"beberlei/assert": "^3.3"
},
"require-dev": {
"php": "^8",
"friendsofphp/php-cs-fixer": "^3.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\\": ""
"D3\\MailConfigChecker\\": "../../../source/modules/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' => Constants::OXID_MODULE_ID,
'id' => $sModuleId,
'title' => [
'de' => $logo.' E-Mail Konfigurationspr&uuml;fung',
'en' => $logo.' Mail Configuration Check Tool',
@ -40,7 +40,7 @@ $aModule = [
'en' => '',
],
'thumbnail' => 'picture.svg',
'version' => '3.0.1.0',
'version' => '1.0.0.1',
'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' => [
'@' . 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',
'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',
],
];

38
migration/README.md Normal file
View File

@ -0,0 +1,38 @@
# Arbeiten mit [Doctrine Migrations](https://www.doctrine-project.org/projects/doctrine-migrations/en/3.6/reference/introduction.html)
Migrations bilden die Veränderung der Datenbankstruktur in programmierter Form ab. Jede Strukturänderung wird in einer einzelnen (jeweils neuen) Migrationsdatei abgelegt, die Teil des Moduls ist.
Passe die `migrations.yml` an Dein Modul an.
## Erstellen eines Skeletons für die erste oder zusätzliche Migrationen
```
./vendor/bin/oe-eshop-doctrine_migration migrations:generate d3moduleid
```
Arbeite die angelegte Datei entsprechend Deinen Anforderungen um.
## Ausführen der noch nicht ausgeführten Migrations
Doctrine überwacht selbst, welche Migrationen schon ausgeführt wurden und verhindert damit mehrfache Ausführungen der selben Migration.
Im OXID-Shop werden Migrations mit folgendem Befehl ausgeführt:
```
./vendor/bin/oe-eshop-db_migrate migrations:migrate
```
Als Argument kann noch die Suite mitgegeben werden, wenn nur bestimmte Migrations ausgeführt werden sollen. Mögliche Angaben sind:
- CE - für alle CE-Migrations
- PE - für alle PE-Migrations
- EE - für alle EE-Migrations
- PR - für alle Projekt-Migrations
- ModuleId - für alle Migrations des jeweiligen Moduls
- ohne Angabe - werden die Migrations aller Suiten nacheinander ausgeführt
## Abweichungen zwischen Doctrine Migrations und dem OXID Migration Wrapper
In den originalen Doctrine Migrations können keine Suiten angegeben werden. Dafür gibt es die Möglichkeit, die Richtung (up / down) und eine Zielversion anzugeben.
Bei OXID können Migrations ausschließlich aufwärts (up) und immer fix bis zur aktuellsten Version ausgeführt werden.

4
migration/migrations.yml Normal file
View File

@ -0,0 +1,4 @@
name: D3 module name
migrations_namespace: D3\ThisModule\Migrations
table_name: d3migrations_modulename
migrations_directory: data

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -1,14 +0,0 @@
<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

@ -1,14 +0,0 @@
<!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

@ -1,39 +0,0 @@
{% 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

@ -1,80 +0,0 @@
{% 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

@ -1,34 +0,0 @@
{% 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

@ -1,71 +0,0 @@
{% 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

@ -1,96 +0,0 @@
{% 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

@ -1,112 +0,0 @@
{% 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" %}