Avoid calling flush() in logger

This is to avoid unintended side effect of trying to save modified
or detached entities.

[MAILPOET-5745]
This commit is contained in:
Jan Jakes
2023-11-30 11:46:04 +01:00
committed by Aschepikov
parent 469bdebf9c
commit 125b0ab03d
6 changed files with 62 additions and 68 deletions

View File

@@ -5,16 +5,53 @@ namespace MailPoet\Logging;
use MailPoet\Doctrine\Repository;
use MailPoet\Entities\LogEntity;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\InvalidStateException;
use MailPoet\Util\Helpers;
use MailPoet\WP\Functions;
use MailPoetVendor\Carbon\Carbon;
use MailPoetVendor\Doctrine\DBAL\Driver\PDO\Connection;
use MailPoetVendor\Doctrine\ORM\EntityManager;
/**
* @extends Repository<LogEntity>
*/
class LogRepository extends Repository {
protected function getEntityClassName() {
return LogEntity::class;
/** @var Functions */
private $wp;
public function __construct(
EntityManager $entityManager,
Functions $wp
) {
parent::__construct($entityManager);
$this->wp = $wp;
}
public function saveLog(LogEntity $log): void {
// Save log entity using DBAL to avoid calling "flush()" on the entity manager.
// Calling "flush()" can have unintended side effects, such as saving unwanted
// changes or trying to save entities that were detached from the entity manager.
$this->entityManager->getConnection()->insert(
$this->entityManager->getClassMetadata(LogEntity::class)->getTableName(),
[
'name' => $log->getName(),
'level' => $log->getLevel(),
'message' => $log->getMessage(),
'raw_message' => $log->getRawMessage(),
'context' => json_encode($log->getContext()),
'created_at' => (
$log->getCreatedAt() ?? Carbon::createFromTimestamp($this->wp->currentTime('timestamp'))
)->format('Y-m-d H:i:s'),
],
);
// sync the changes with the entity manager
if ($this->entityManager->isOpen()) {
$lastInsertId = (int)$this->entityManager->getConnection()->lastInsertId();
$log->setId($lastInsertId);
$this->entityManager->getUnitOfWork()->registerManaged($log, ['id' => $log->getId()], []);
$this->entityManager->refresh($log);
}
}
/**
@@ -94,4 +131,16 @@ class LogRepository extends Repository {
->getQuery()
->getSingleColumnResult();
}
public function persist($entity): void {
throw new InvalidStateException('Use saveLog() instead to avoid unintended side effects');
}
public function flush(): void {
throw new InvalidStateException('Use saveLog() instead to avoid unintended side effects');
}
protected function getEntityClassName() {
return LogEntity::class;
}
}