-1

我正在尝试在 symfony 3.4 中使用锁定组件,就像在 https://symfony.com/doc/3.4/components/lock.html上描述的那样

我想防止来自不同用户的多个数据更改。

例如 user1 用数据调用同一个公司表单,然后 user2

我如何告诉 user2,编辑数据被 user1(包括用户名)阻止?

更新: 它用于后端,很多员工编辑客户,订单等数据。此表格仅用于编辑。这意味着,如果他们想更新一些数据,他们点击“编辑”。在将数据加载到表单之前,当其他员工更改此记录时,应通知他们。员工有时需要一些时间来改变一切。如果员工在保存时收到消息,他们必须返回,重新加载数据并重新开始。

我的控制器的一个例子:

 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;
        }
4

1 回答 1

2

你不能(锁不能有任何元数据),但你可能一开始就不想要这个。

在这种情况下,您在用户打开编辑页面时创建一个锁,并在用户提交表单时释放它。但是如果用户打开页面并且没有提交表单怎么办?为什么用户甚至不能查看表单?

这看起来像一个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');
}

免责声明:代码未经测试,仅作为示例该解决方案的外观。

于 2019-03-06T10:11:24.253 回答