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:
- Support wildcard patterns in the blacklist (e.g. *@amazon.com)
- Fetch the blacklist once and loop through it instead of separate queries
Here is the current code:
use MonologLogger;
use ShopwareCoreFrameworkContext;
use ShopwareCoreFrameworkDataAbstractionLayerEntityRepository;
use SwaProductReviewsComponentsLoggerHelper;
use ShopwareCoreFrameworkDataAbstractionLayerSearchCriteria;
use ShopwareCoreFrameworkDataAbstractionLayerSearchFilterEqualsFilter;
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.
2
Answers
To extend the plugin for wildcards and fetch the blacklist once, you can follow these steps:
$blacklistCache
.$blacklistCache
and use a helper methodmatchesWildcard
to check for wildcard matches.matchesWildcard
to check the email against the wildcard pattern usingpreg_match
method.For the part of the performance i don’t really see any issue with your approach. As you only make one additional DB call per web request i see no real performance issue here. The alternative would be to cache the blacklist e.g. in redis but that would make your plugin way more complicated as you also have to take care of invalidation of the blacklist, and you also have to implement the lookup in memory instead of using the DB for that.
Regarding the flexibility of wildcards you can use an
ContainsFilter
which will translate to anLIKE %term%
query under the hood.If you want to be even more flexible i wouldn’t use the shopware DAL repository, but rather use plain SQL, so out of the box you could
?
as wildcards, but if you go in that direction beware of SQL injections.