Allow to to disable the saving of changed or deleted data.

Also it is possible to only save the information which fields were changed, not the data in it.
This commit is contained in:
Jan Böhmer 2020-02-23 21:04:16 +01:00
parent 2bc6a2be3c
commit b5bc096972
4 changed files with 76 additions and 5 deletions

14
.env
View file

@ -59,3 +59,17 @@ EMAIL_SENDER_EMAIL=noreply@partdb.changeme
# Set this to 1 to allow reset of a password per email
ALLOW_EMAIL_PW_RESET=0
######################################################################################
# History/Eventlog related settings
######################################################################################
# If you want to use full timetrave functionality
# Save which fields were changed in a ElementEdited log entry
HISTORY_SAVE_CHANGED_FIELDS=1
# Save the old data in the ElementEdited log entry (warning this could increase the database size in short time)
HISTORY_SAVE_CHANGED_DATA=0
# Save the data of an element that gets removed into log entry. This allows to undelete an element
HISTORY_SAVE_REMOVED_DATA=0

View file

@ -74,6 +74,10 @@ services:
- { name: "doctrine.orm.entity_listener" }
App\EventSubscriber\EventLoggerSubscriber:
arguments:
$save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
$save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
$save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
tags:
- { name: 'doctrine.event_subscriber' }

View file

@ -68,7 +68,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
*/
public function hasChangedFieldsInfo(): bool
{
return $this->hasOldDataInformations();
return isset($this->extra['f']) || $this->hasOldDataInformations();
}
/**
@ -77,9 +77,28 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
*/
public function getChangedFields(): array
{
if ($this->hasOldDataInformations()) {
return array_keys($this->getOldData());
}
if (isset($this->extra['f'])) {
return $this->extra['f'];
}
return [];
}
/**
* Set the fields that were changed during this element change.
* @param string[] $changed_fields The names of the fields that were changed during the elements
* @return $this
*/
public function setChangedFields(array $changed_fields): self
{
$this->extra['f'] = $changed_fields;
return $this;
}
/**
* Sets the old data for this entry.
* @param array $old_data

View file

@ -25,6 +25,7 @@ use App\Entity\LogSystem\AbstractLogEntry;
use App\Entity\LogSystem\ElementCreatedLogEntry;
use App\Entity\LogSystem\ElementDeletedLogEntry;
use App\Entity\LogSystem\ElementEditedLogEntry;
use App\Entity\UserSystem\User;
use App\Services\LogSystem\EventCommentHelper;
use App\Services\LogSystem\EventLogger;
use Doctrine\Common\EventSubscriber;
@ -37,15 +38,26 @@ use Symfony\Component\Serializer\SerializerInterface;
class EventLoggerSubscriber implements EventSubscriber
{
protected const MAX_STRING_LENGTH = 2000;
protected $logger;
protected $serializer;
protected $eventCommentHelper;
protected $save_changed_fields;
protected $save_changed_data;
protected $save_removed_data;
public function __construct(EventLogger $logger, SerializerInterface $serializer, EventCommentHelper $commentHelper)
public function __construct(EventLogger $logger, SerializerInterface $serializer, EventCommentHelper $commentHelper,
bool $save_changed_fields, bool $save_changed_data, bool $save_removed_data)
{
$this->logger = $logger;
$this->serializer = $serializer;
$this->eventCommentHelper = $commentHelper;
$this->save_changed_fields = $save_changed_fields;
$this->save_changed_data = $save_changed_data;
$this->save_removed_data = $save_removed_data;
}
public function onFlush(OnFlushEventArgs $eventArgs)
@ -61,7 +73,12 @@ class EventLoggerSubscriber implements EventSubscriber
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($this->validEntity($entity)) {
$log = new ElementEditedLogEntry($entity);
if ($this->save_changed_data) {
$this->saveChangeSet($entity, $log, $uow);
} elseif ($this->save_changed_fields) {
$changed_fields = array_keys($uow->getEntityChangeSet($entity));
$log->setChangedFields($changed_fields);
}
//Add user comment to log entry
if ($this->eventCommentHelper->isMessageSet()) {
$log->setComment($this->eventCommentHelper->getMessage());
@ -77,7 +94,9 @@ class EventLoggerSubscriber implements EventSubscriber
if ($this->eventCommentHelper->isMessageSet()) {
$log->setComment($this->eventCommentHelper->getMessage());
}
if ($this->save_removed_data) {
$this->saveChangeSet($entity, $log, $uow);
}
$this->logger->log($log);
}
}
@ -94,6 +113,21 @@ class EventLoggerSubscriber implements EventSubscriber
$changeSet = $uow->getEntityChangeSet($entity);
$old_data = array_diff(array_combine(array_keys($changeSet), array_column($changeSet, 0)), [null]);
//Restrict length of string fields, to save memory...
$old_data = array_map(function ($value) {
if (is_string($value)) {
return mb_strimwidth($value, 0, self::MAX_STRING_LENGTH, '...');
}
return $value;
}, $old_data);
//Dont save sensitive fields to log
if ($entity instanceof User) {
unset($old_data['password'], $old_data['pw_reset_token'], $old_data['backupCodes']);
}
$logEntry->setOldData($old_data);
}