1

我在我的 SF 3.3 项目中使用 EasyAdmin,但我需要实现与 EasyAdmin 的构建方式不同的东西。看看下面的图片:

在此处输入图像描述

正如您可能注意到的,一个用户可以在多个GroupingRole. 拥有这些信息的挑战是:

  • 检查用户是否已分配给任何其他人GroupingRole
  • 如果条件满足条件,则显示警告消息“用户 A 已分配给 GroupingRole A”并阻止创建记录。(此消息可能在弹出窗口、javascript 警报或来自 Bootstrap 的警报中 - 因为 EA 已经使用它)
  • 当管理员再次单击“保存更改”时,应创建记录。

我想用这种方法实现的是提醒管理员用户已经加入任何其他组,但不要阻止他创建记录。

我已经通过覆盖该prePersist实体的方法来实现它的某些部分(见下文):

class AdminController extends BaseAdminController
{
    /**
     * Check if the users has been assigned to any group
     */
    protected function prePersistGroupingRoleEntity($entity)
    {
        $usersToGroupRoleEntities = $this->em->getRepository('CommonBundle:UsersToGroupRole')->findAll();
        $usersToGroupRole         = [];

        /** @var UsersToGroupRole $groupRole */
        foreach ($usersToGroupRoleEntities as $groupRole) {
            $usersToGroupRole[$groupRole->getGroupingRoleId()][] = $groupRole->getUsersId();
        }

        $usersInGroup = [];

        /** @var Users $userEntity */
        foreach ($entity->getUsersInGroup() as $userEntity) {
            foreach ($usersToGroupRole as $group => $users) {
                if (\in_array($userEntity->getId(), $users, true)) {
                    $usersInGroup[$group][] = $userEntity->getId();
                }
            }
        }

        $groupingRoleEnt = $this->em->getRepository('CommonBundle:GroupingRole');
        $usersEnt        = $this->em->getRepository('CommonBundle:Users');

        $message = [];
        foreach ($usersInGroup as $group => $user) {
            foreach($user as $usr) {
                $message[] = sprintf(
                    'The user %s already exists in %s group!',
                    $usersEnt->find($usr)->getEmail(),
                    $groupingRoleEnt->find($group)->getName()
                );
            }
        }
    }
}

我不知道如何停止要创建的记录,而是在第一次单击按钮时显示警告,因为第二次并发出警告,我应该允许创建记录。

任何人都可以给我一些想法和/或建议吗?

更新:添加实体信息

除了上面显示的代码之外,还有涉及该过程的实体:

/**
 * @ORM\Entity
 * @ORM\Table(name="grouping_role")
 */
class GroupingRole
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer",unique=true,nullable=false)
     * @ORM\GeneratedValue
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="role_name", type="string", nullable=false)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="role_description", type="string", nullable=false)
     */
    private $description;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Schneider\QuoteBundle\Entity\Distributor", inversedBy="groupingRole")
     * @ORM\JoinTable(name="grouping_to_role",
     *   joinColumns={
     *     @ORM\JoinColumn(name="grouping_role_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="DistributorID", referencedColumnName="DistributorID", nullable=false)
     *   }
     * )
     *
     * @Assert\Count(
     *      min = 1,
     *      minMessage = "You must select at least one Distributor"
     * )
     */
    private $distributorGroup;

    /**
     * @var ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="CommonBundle\Entity\Users", inversedBy="usersGroup")
     * @ORM\JoinTable(name="users_to_group_role",
     *   joinColumns={
     *     @ORM\JoinColumn(name="grouping_role_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="users_id", referencedColumnName="users_id", nullable=false)
     *   }
     * )
     *
     * @Assert\Count(
     *      min = 1,
     *      minMessage = "You must select at least one user"
     * )
     */
    private $usersInGroup;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->distributorGroup = new ArrayCollection();
        $this->usersInGroup     = new ArrayCollection();
    }
}

/**
 * @ORM\Entity()
 * @ORM\Table(name="users_to_group_role")
 */
class UsersToGroupRole
{
    /**
     * @var int
     *
     * @ORM\Id()
     * @ORM\Column(type="integer",nullable=false)
     * @Assert\Type(type="integer")
     * @Assert\NotNull()
     */
    protected $usersId;

    /**
     * @var int
     *
     * @ORM\Id()
     * @ORM\Column(type="integer", nullable=false)
     * @Assert\Type(type="integer")
     * @Assert\NotNull()
     */
    protected $groupingRoleId;
}
4

1 回答 1

1

在 EasyAdminBundle 中使用表单验证方法的一个小例子:

class AdminController extends EasyAdminController
{
    // ...

    protected function create<EntityName>EntityFormBuilder($entity, $view)
    {
        $builder = parent::createEntityFormBuilder($entity, $view);

        $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
            $data = $event->getData();

            $flag = false;
            if (isset($data['flag'])) {
                $flag = $data['flag'];
                unset($data['flag']);
            }
            $key = md5(json_encode($data));

            if ($flag !== $key) {
                $event->getForm()->add('flag', HiddenType::class, ['mapped' => false]);
                $data['flag'] = $key;
                $event->setData($data);
            }
        });

        return $builder;
    }

    protected function get<EntityName>EntityFormOptions($entity, $view)
    {
        $options = parent::getEntityFormOptions($entity, $view);

        $options['validation_groups'] = function (FormInterface $form) {
            if ($form->has('flag')) {
                return ['Default', 'CheckUserGroup'];
            }

            return ['Default'];
        };

        $options['constraints'] = new Callback([
            'callback' => function($entity, ExecutionContextInterface $context) {
                // validate here and adds the violation if applicable.

                $context->buildViolation('Warning!')
                    ->atPath('<field>')
                    ->addViolation();
            },
            'groups' => 'CheckUserGroup',
        ]);

        return $options;
    }
}

请注意,PRE_SUBMIT在验证过程发生之前触发事件。

在提交表单时第一次(动态地)添加该flag字段,因此CheckUserGroup添加了验证组并且回调约束完成了它的工作。之后,第二次提交的数据中包含flaghash(如果数据没有变化)该flag字段没有添加,所以也没有添加验证组,实体被保存(如果回调约束没有添加违规)第一次)。

此外(如果您愿意),您可以在目标实体的自定义表单类型中完成所有这些操作。

于 2017-11-16T17:31:31.727 回答