У меня есть приложение, в котором я должен регистрировать каждое пользовательское действие, какой URL он посещает, было ли это действие успешным или нет. Так что для этого я сделал слушателя, чтобы проверить каждый посещенный URL и LogFactory следующим образом:
class UserLogFactory
{
private $container;
private $entityManager;
private $platform;
private $logRepository;
private $request;
private $userLogger;
public function __construct(ContainerInterface $container,
EntityManagerInterface $entityManager,
UserPlatformChecker $platform,
UserLogTypeRepository $logRepository,
RequestStack $request,
LoggerInterface $userLogger
)
{
$this->container = $container;
$this->entityManager = $entityManager;
$this->platform = $platform;
$this->logRepository = $logRepository;
$this->request = $request;
$this->userLogger = $userLogger;
}
public function userLogFactory($logType, $logText)
{
$request = $this->request->getCurrentRequest();
$token = $this->container->get('security.token_storage')->getToken();
if ($token === null || !($token->getUser() instanceof User)) {
return;
}
$user = $token->getUser();
$platform = $this->platform->getPlatform($request);
$ip = $request->getClientIp();
$date = new \DateTime('now');
$url = $request->getUri();
$log = new UserLog();
$log->setUser($user);
$log->setType($logType);
$log->setPlatform($platform);
$log->setIp($ip);
$log->setDate($date);
$log->setUrl($url);
$log->setLogText($logText);
$this->entityManager->persist($log);
$this->entityManager->flush();
}
}
Я регистрирую действия в своих контроллерах, например, когда какой-то UserAdmin пытается редактировать другого пользователя, я делаю что-то вроде этого:
public function editUser(User $user, Request $request, UserPasswordEncoderInterface $passwordEncoder, EntityManagerInterface $entityManager)
{
// First form for edit User //
$userForm = $this->createForm(EditUserType::class, $user);
$userForm->handleRequest($request);
if ($userForm->isSubmitted() && $userForm->isValid()) {
$entityManager->flush();
$this->addFlash('notice', 'Profile has been edited');
$logType = $this->logRepository->find(UserLogType::SUCCESS_ACTION);
$this->userLogFactory->userLogFactory($logType, 'User edited user profile.');
return $this->redirectToRoute('user_list');
}
elseif ($userForm->isSubmitted() && !$userForm->isValid()) {
$logType = $this->logRepository->find(UserLogType::FAILED_ACTION);
$this->userLogFactory->userLogFactory($logType, 'User has failed to edit user profile.');
}
И там, где моя проблема, UserAdmin пытается изменить имя пользователя для уже существующего в базе данных, у меня есть ошибка SQL:
An exception occurred while executing 'UPDATE user SET login = ? WHERE id = ?' with params ["aaa", 2]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'aaa' for key 'UNIQ_8D93D649AA08CB10'
Я понятия не имею, что я должен изменить, чтобы получить нормальное сообщение проверки формы, например Пользователь с таким логином уже существует.
Я знаю, что что-то не так с этим UserLogFactory, потому что без него все работает нормально, но я не могу определить причину.
EDIT . Вот мой пользовательский объект:
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @UniqueEntity("login")
*/
class User implements UserInterface
{
public const ROLE_USER = 'ROLE_USER';
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=10, unique=true)
*/
private $login;
/**
* @ORM\Column(type="string", length=255)
*/
private $password;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\UserPermissionList")
* @ORM\JoinTable(name="user_permisions")
*/
private $permissions;
ETC.