Как использовать Lock Component в Symfony3.4 с именем пользователя - PullRequest
0 голосов
/ 06 марта 2019

Я пытаюсь использовать компонент блокировки в symfony 3.4, как это описано на https://symfony.com/doc/3.4/components/lock.html

Я хочу предотвратить множественные изменения данных от разных пользователей.

Например, user1 вызывает ту же форму компании с данными, затем user2

Как я могу сказать пользователю2, что редактирование данных заблокировано пользователем1 (включая имя пользователя)?

UPDATE: Он используется в бэкэнде, где много сотрудников редактируют данные клиентов, заказ и т. Д. эта форма только для редактирования. это означает, что, если они хотят обновить некоторые данные, они нажимают «изменить». Они должны быть проинформированы, когда другой сотрудник изменяет эту запись, прежде чем данные будут загружены в форму. Иногда работнику требуется некоторое время, чтобы все изменить. Если сотрудник получает сообщение при сохранении, он должен вернуться назад, перезагрузить данные и начать все заново.

пример из моего контроллера:

 public function CompanyEdit(Request $request)
    {

        $error = null;
        $company_id                                 = $request->get('id');
//        if (!preg_match('/^\d+$/', $company_id)){
//            return $this->showError();
//        }

        $store = new SemaphoreStore();
        $factory = new Factory($store);
        $lock = $factory->createLock('company-edit-'.$company_id, 30);

        if(!$lock->acquire()) {
             //send output with username
            // this data is locked by user xy
            return 0;
        }

        $company = $this->getDoctrine()->getRepository(Company::class)->find($company_id);
        $payment = $this->getDoctrine()->getRepository(Companypay::class)->findOneBy(array('company_id' => $company_id));

        $form = $this->createFormBuilder()
            ->add('company', CompanyFormType::class, array(
                'data_class' => 'AppBundle\Entity\Company',
                'data' => $company
            ))
            ->add('payment', CompanyPayFormType::class, array(
                'data_class' => 'AppBundle\Entity\CompanyPay',
                'data' => $payment

            ))
            ->getForm();

        $form->handleRequest($request);
        $company = $form->get('company')->getData();
        $payment = $form->get('payment')->getData();

        if ($form->isSubmitted() && $form->isValid()) {
            $event = new FormEvent($form, $request);

            if ($payment->getCompanyId() == null) {
                $payment->setCompanyId($company->getId());
            }

            try {
                $this->getDoctrine()->getManager()->persist($company);
                $this->getDoctrine()->getManager()->persist($payment);
                $this->getDoctrine()->getManager()->flush();
                $this->container->get('app.logging')->write('Kundendaten geändert', $company->getId());
            } catch (PDOException $e) {
                $error = $e->getMessage();
            }
            if (null === $response = $event->getResponse()) {

                return $this->render('customer/edit.html.twig', [
                    'form' => $form->createView(),
                    'company' => $company,
                    'error' => $error,
                    'success' => true
                ]);
            }
            $lock->release();
            return $response;
        }

1 Ответ

1 голос
/ 06 марта 2019

Вы не можете (у замков не может быть никаких метаданных), но вы, вероятно, вообще не хотите этого.

В этом случае вы создаете блокировку, когда пользователь открывает страницу редактирования, и отпускаете ее, когда пользователь отправляет форму. Но что если пользователи откроют страницу и не отправят форму? И почему пользователь не может даже просмотреть форму?

Это похоже на XY-проблему . Я думаю, что вы пытаетесь запретить пользователям перезаписывать данные, не зная. Вместо этого вы можете добавить метку времени или хэш к форме, которая изменяется после изменения объекта. Например:

<form type="hidden" name="updatedAt" value="{{ company.updatedAt()|date('U') }}" />

А в вашей форме:

<?php
if ($company->getUpdatedAt()->format('U') !== $form->get('updatedAt')->getData()) {
    throw new \LogicException('The entity has been changed after you opened the page');
}

Отказ от ответственности: код не тестировался и только в качестве примера, как может выглядеть это решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...