I have developed a Shopware 6 plugin that checks if an email is in a blacklist before allowing reviews. It works but currently does a database query for every email being checked. If I am in a scheduled task run that sends out 50 emails and I have 1000 entries with wildcard entries, this code won't work anymore.
I would like to optimize the plugin to:
Here is the current code:
use Monolog\Logger;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Swa\ProductReviews\Components\LoggerHelper;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
class MailWithBlacklist {
private EntityRepository $blacklistRepository;
protected LoggerHelper $loggerHelper;
public function __construct(EntityRepository $blacklistRepository, LoggerHelper $loggerHelper) {
$this->blacklistRepository = $blacklistRepository;
$this->loggerHelper = $loggerHelper;
}
/**
*
* @param string $email
* @param Context $context
* @return bool
*/
public function isEmailBlacklisted(string $email, Context $context): bool
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('email', $email));
$blacklistEntry = $this->blacklistRepository->search($criteria, $context)->first();
$this->loggerHelper->addDirectRecord(Logger::DEBUG, 'end of isEmailBlacklisted' , ['blacklistEntry' => $blacklistEntry]);
return $blacklistEntry !== null;
}
}
How can I modify this code?
Any help is appreciated.
To extend the plugin for wildcards and fetch the blacklist once, you can follow these steps:
$blacklistCache
.$blacklistCache
and use a helper method matchesWildcard
to check for wildcard matches.matchesWildcard
to check the email against the wildcard pattern using preg_match
method.class MailWithBlacklist {
private $blacklistCache;
private EntityRepository $blacklistRepository;
protected LoggerHelper $loggerHelper;
public function __construct(EntityRepository $blacklistRepository, LoggerHelper $loggerHelper) {
$this->blacklistRepository = $blacklistRepository;
$this->loggerHelper = $loggerHelper;
}
/**
*
* @param string $email
* @param Context $context
* @return bool
*/
public function isEmailBlacklisted(string $email, Context $context): bool
{
$criteria = new Criteria();
$this->blacklistCache = $this->blacklistRepository->search($criteria, $context)->getEntities();
foreach ($this->blacklistCache as $entry) {
if ($this->matchesWildcard($email, $entry->getEmail())) {
return true;
}
}
return false;
}
private function matchesWildcard(string $email, string $pattern): bool
{
$pattern = preg_quote($pattern, '/');
$pattern = str_replace('\*', '.*', $pattern);
return (bool) preg_match("/$pattern/i", $email);
}
}