diff --git a/migrations/Version20221216224745.php b/migrations/Version20221216224745.php new file mode 100644 index 00000000..63bb535e --- /dev/null +++ b/migrations/Version20221216224745.php @@ -0,0 +1,72 @@ +addSql('ALTER TABLE `log` DROP FOREIGN KEY FK_8F3F68C56B3CA4B'); + $this->addSql('ALTER TABLE `log` ADD username VARCHAR(255) NOT NULL, CHANGE id_user id_user INT DEFAULT NULL, CHANGE level level TINYINT(4) NOT NULL'); + $this->addSql('ALTER TABLE `log` ADD CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES `users` (id) ON DELETE SET NULL'); + + //Fill the username column for existing logs + $this->addSql('UPDATE `log` LEFT JOIN `users` ON `log`.id_user = `users`.id SET `log`.username = `users`.name'); + } + + public function mySQLDown(Schema $schema): void + { + $this->addSql('ALTER TABLE `log` DROP FOREIGN KEY FK_8F3F68C56B3CA4B'); + $this->addSql('ALTER TABLE `log` DROP username, CHANGE id_user id_user INT NOT NULL, CHANGE level level TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE `log` ADD CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES users (id)'); + } + + + public function sqLiteUp(Schema $schema): void + { + $this->addSql('CREATE TEMPORARY TABLE __temp__log AS SELECT id, id_user, datetime, level, target_id, target_type, extra, type FROM log'); + $this->addSql('DROP TABLE log'); + $this->addSql('CREATE TABLE log (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_user INTEGER DEFAULT NULL, datetime DATETIME NOT NULL, level TINYINT(4) NOT NULL, target_id INTEGER NOT NULL, target_type SMALLINT NOT NULL, extra CLOB NOT NULL --(DC2Type:json) + , type SMALLINT NOT NULL, username VARCHAR(255) DEFAULT "" NOT NULL, CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES "users" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO log (id, id_user, datetime, level, target_id, target_type, extra, type) SELECT id, id_user, datetime, level, target_id, target_type, extra, type FROM __temp__log'); + $this->addSql('DROP TABLE __temp__log'); + $this->addSql('CREATE INDEX log_idx_datetime ON log (datetime)'); + $this->addSql('CREATE INDEX log_idx_type_target ON log (type, target_type, target_id)'); + $this->addSql('CREATE INDEX log_idx_type ON log (type)'); + $this->addSql('CREATE INDEX IDX_8F3F68C56B3CA4B ON log (id_user)'); + + //Fill the username column for existing logs + $this->addSql('UPDATE log SET username = (SELECT name FROM users WHERE id = log.id_user)'); + + //$this->addSql('UPDATE log JOIN `users` ON log.id_user = `users`.id SET log.username = `users`.name'); + } + + public function sqLiteDown(Schema $schema): void + { + $this->addSql('CREATE TEMPORARY TABLE __temp__log AS SELECT id, id_user, datetime, level, target_id, target_type, extra, type FROM log'); + $this->addSql('DROP TABLE log'); + $this->addSql('CREATE TABLE log (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, id_user INTEGER NOT NULL, datetime DATETIME NOT NULL, level BOOLEAN NOT NULL, target_id INTEGER NOT NULL, target_type SMALLINT NOT NULL, extra CLOB NOT NULL --(DC2Type:json) + , type SMALLINT NOT NULL, CONSTRAINT FK_8F3F68C56B3CA4B FOREIGN KEY (id_user) REFERENCES users (id) ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO log (id, id_user, datetime, level, target_id, target_type, extra, type) SELECT id, id_user, datetime, level, target_id, target_type, extra, type FROM __temp__log'); + $this->addSql('DROP TABLE __temp__log'); + $this->addSql('CREATE INDEX IDX_8F3F68C56B3CA4B ON log (id_user)'); + $this->addSql('CREATE INDEX log_idx_type ON log (type)'); + $this->addSql('CREATE INDEX log_idx_type_target ON log (type, target_type, target_id)'); + $this->addSql('CREATE INDEX log_idx_datetime ON log (datetime)'); + + } +} diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index a7b9986a..37be510d 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -157,18 +157,6 @@ class UserController extends AdminPages\BaseAdminController return $this->_new($request, $em, $importer, $entity); } - protected function deleteCheck(AbstractNamedDBElement $entity): bool - { - if ($entity instanceof User) { - //TODO: Find a better solution - $this->addFlash('error', 'Currently it is not possible to delete a user, as this would break the log... This will be implemented later...'); - - return false; - } - - return true; - } - /** * @Route("/{id}", name="user_delete", methods={"DELETE"}, requirements={"id"="\d+"}) */ diff --git a/src/DataTables/LogDataTable.php b/src/DataTables/LogDataTable.php index d1a4a89f..4805345a 100644 --- a/src/DataTables/LogDataTable.php +++ b/src/DataTables/LogDataTable.php @@ -188,10 +188,19 @@ class LogDataTable implements DataTableTypeInterface 'render' => function ($value, AbstractLogEntry $context) { $user = $context->getUser(); + //If user was deleted, show the info from the username field + if ($user === null) { + return sprintf( + '@%s [%s]', + htmlentities($context->getUsername()), + $this->translator->trans('log.target_deleted'), + ); + } + return sprintf( '%s', $this->urlGenerator->generate('user_info', ['id' => $user->getID()]), - $user->getFullName(true) + htmlentities($user->getFullName(true)) ); }, ]); diff --git a/src/Entity/LogSystem/AbstractLogEntry.php b/src/Entity/LogSystem/AbstractLogEntry.php index c48612d0..840d7a31 100644 --- a/src/Entity/LogSystem/AbstractLogEntry.php +++ b/src/Entity/LogSystem/AbstractLogEntry.php @@ -143,10 +143,16 @@ abstract class AbstractLogEntry extends AbstractDBElement /** @var User The user which has caused this log entry * @ORM\ManyToOne(targetEntity="App\Entity\UserSystem\User", fetch="EAGER") - * @ORM\JoinColumn(name="id_user", nullable=false) + * @ORM\JoinColumn(name="id_user", nullable=true, onDelete="SET NULL") */ protected ?User $user = null; + /** + * @var string The username of the user which has caused this log entry (shown if the user is deleted) + * @ORM\Column(type="string", nullable=false) + */ + protected string $username = ''; + /** @var DateTime The datetime the event associated with this log entry has occured * @ORM\Column(type="datetime", name="datetime") */ @@ -203,9 +209,22 @@ abstract class AbstractLogEntry extends AbstractDBElement { $this->user = $user; + //Save the username for later use + $this->username = $user->getUsername(); + return $this; } + /** + * Retuns the username of the user that caused the event (useful if the user was deleted). + * + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + /** * Returns the timestamp when the event that caused this log entry happened. */