如何在Symfony 3中使用具有多对多关系的表格和FOS Rest Bundle

时间:2019-02-07 13:32:39

标签: forms symfony many-to-many fosrestbundle

我将Symfony 3.4与FOSRestBundle和JMSSerializer一起使用。 我已经为我的组实体创建了一个表单,但是我的UserSystem属性存在很多问题。 我尝试了两种解决方案,但无法修复错误:(

我的实体(组和用户系统)

class Group extends BaseGroup
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(name="[ID_Groupe]", type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     *
     * @Serializer\Groups({"group", "group_list"})
     */
    protected $id;

    /**
     * List of groups that contain this group
     *
     * @var Collection
     * @ORM\ManyToMany(targetEntity="OL\FactoryBundle\Entity\Group", mappedBy="groupsContained")
     *
     * @Serializer\MaxDepth(2)
     * @Serializer\Groups({"group"})
     */
    protected $groupsContainer;

    /**
     * List of groups in this group
     *
     * @var Collection
     * @ORM\ManyToMany(targetEntity="OL\FactoryBundle\Entity\Group", inversedBy="groupsContainer")
     * @ORM\JoinTable(name="[1L_Groupes_Vers_Groupes]",
     *      joinColumns={@ORM\JoinColumn(name="[ID_Groupe_Conteneur]", referencedColumnName="[ID_Groupe]")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="[ID_Groupe_Contenu]", referencedColumnName="[ID_Groupe]")}
     *      )
     * @Serializer\MaxDepth(2)
     * @Serializer\Groups({"group"})
     */
    protected $groupsContained;

    /**
     * @var Collection
     *
     * @ORM\ManyToMany(targetEntity="OL\FactoryBundle\Entity\UserSystem", inversedBy="groups", cascade={"persist", "remove"})
     * @ORM\JoinTable(name="[1L_Utilisateurs_Systemes_Dans_Groupes]",
     *      joinColumns={@ORM\JoinColumn(name="[ID_Groupe]", referencedColumnName="[ID_Groupe]")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="[ID_Utilisateur_Systeme]", referencedColumnName="[ID_Utilisateur_Systeme]")}
     *      )
     *
     * @Serializer\Groups({"group"})
     */
    protected $usersSystem;

    // some attributes ... //

    /**
     * Group constructor.
     *
     * @param string $name
     */
    public function __construct(string $name = "UNKNOWN")
    {
        parent::__construct($name);
        $this->roleGroupByCompany = new ArrayCollection();
        $this->roleGroupByScenarioTemplate = new ArrayCollection();
        $this->usersSystem = new ArrayCollection();
    }

    // continuation of the entity....
}

class UserSystem extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="[ID_Utilisateur_Systeme]")
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * @var Collection
     *
     * @ORM\ManyToMany(targetEntity="OL\FactoryBundle\Entity\Group", mappedBy="usersSystem")
     *
     * @Serializer\Groups({"user_system"})
     */
    protected $groups;

    // some attributes ... //

    /**
     * UserSystem constructor.
     */
    public function __construct()
    {
        parent::__construct();
        $this->groups = new ArrayCollection();
        $this->includedRoleUserByCompany = new ArrayCollection();
        $this->includedRoleUserByScenarioTemplate = new ArrayCollection();
        $this->excludedRoleUserByCompany = new ArrayCollection();
        $this->excludedRoleUserByScenarioTemplate = new ArrayCollection();
        $this->includedRoles = new ArrayCollection();
        $this->excludedRoles = new ArrayCollection();
        $this->user1Life = new ArrayCollection();
    }

    // continuation of the entity....
}

我的表格

class GroupType extends AbstractType
{
    /**
     * @var EntityManagerInterface
     */
    private $entityManager;

    /**
     * ScreenType constructor.
     *
     * @param EntityManagerInterface $entityManager
     */
    public function __construct(EntityManagerInterface $entityManager) {
        $this->entityManager = $entityManager;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('label', TextType::class, [
            'required' => false,
        ]);

        $builder->add('groups_contained', CollectionType::class, array(
            'required' => false,
            'entry_type' => GroupEntityType::class,
            'allow_add' => true,
            'allow_delete' => true,
        ));
        $builder->get('groups_contained')
            ->addModelTransformer(new ArrayIntegerToGroupEntityTransformer($this->entityManager));

// Test 1
        $builder->add('users_system', CollectionType::class, array(
            'required' => false,
            'entry_type' => UserSystemEntityType::class,
            'allow_add' => true,
            'allow_delete' => true,
        ));
        $builder->get('users_system')
            ->addModelTransformer(new ArrayStringToUserSystemEntityTransformer($this->entityManager));
// end Test 1

// Test 2
        $builder->add('users_system', EntityType::class, [
            "class" => 'OLFactoryBundle:UserSystem',
            "choice_name" => 'username',
            "expanded" => true,
            "multiple" => true,
        ]);
// end Test 2
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Group::class,
            'allow_extra_fields' => true,
            'csrf_protection' => false
        ]);
    }
}

我的ModelTransformer ArrayStringToUserSystemEntityTransformer

class ArrayStringToUserSystemEntityTransformer implements DataTransformerInterface
{
    /**
     * @var EntityManagerInterface
     */
    protected $entityManager;

    /**
     * IntegerToScenarioGoalEntityTransformer constructor.
     *
     * @param EntityManagerInterface $entityManager
     */
    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @param mixed $values
     * @return mixed
     */
    public function transform($values)
    {
        $array = [];
        /** @var PersistentCollection $value */
        foreach ($values as $userSystem) {
            /** @var UserSystem $userSystem */
            $array[] = [
                "username" => $userSystem->getUsername(),
                "_link" => $userSystem->getLink(),
            ];
        }
        return $array;
    }

    /**
     * @param mixed $values
     * @return mixed|null|object
     * @throws \Exception
     */
    public function reverseTransform($values)
    {
        $repository = $this->entityManager->getRepository(UserSystem::class);
        $objects = new ArrayCollectionCustom();
        foreach ($values as $value) {
            if (empty($value["username"])) {
                continue;
            }
            $object = $repository->findOneBy(["username" => $value["username"]]);
            $objects->add($object);
        }
        return $objects;
    }
}

我的控制器

/**
 * Class APIGroupController
 *
 * @package OL\FactoryBundle\Controller
 * @Route("/api/groups")
 */
class APIGroupController extends CommonController
{
    // others routes...//

    /**
     * @Rest\Put(
     *     path="/{id}",
     *     name="group_put",
     *     requirements={"id"="\d+"}
     * )
     * @param Request $request
     * @param Group $group
     * @return null|object|Group|\Symfony\Component\Form\FormInterface|JsonResponse
     * @Rest\View(serializerGroups={"group", "user_system_list"}, serializerEnableMaxDepthChecks=true)
     * @throws \Exception
     */
    public function editAction(Request $request, Group $group)
    {
        if (empty($group)) {
            return new JsonResponse(['message' => 'Group not found'], Response::HTTP_NOT_FOUND);
        }

        $form = $this->createForm(GroupType::class, $group);
        $form->submit($request->request->all());
        if ($form->isValid()) {
            $this->getDoctrine()->getRepository(Group::class)->save($group);
            return $group;
        } else {
            return $form;
        }
    }
}

请求主体,api / groups / 1(.JSON)

{
    "id": 1,
    "label": "DIRECTION",
    "_link": {
        "self": "groups/1"
    },
    "_read_only": [
        "group_container"
    ],
    "groups_container": [
        {
            "id": 2,
            "label": "SALES_MANAGER",
            "_link": {
                "self": "groups/2"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        },
        {
            "id": 3,
            "label": "DEVELOPMENT_MANAGER",
            "_link": {
                "self": "groups/3"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        }
    ],
    "groups_contained": [
        {
            "id": 0,
            "label": "ADMINISTRATOR",
            "_link": {
                "self": "groups/0"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        }
    ],
    "users_system": [
        {
            "username": "director",
            "_link": {
                "self": "userssystem/director"
            }
        },
        {
            "username": "director-exclude",
            "_link": {
                "self": "userssystem/director-exclude"
            }
        },
        {
            "username": "multi",
            "_link": {
                "self": "userssystem/multi"
            }
        }
    ]
}

我希望我的实体已更新

{
    "id": 1,
    "label": "DIRECTION",
    "_link": {
        "self": "groups/1"
    },
    "_read_only": [
        "group_container"
    ],
    "groups_container": [
        {
            "id": 2,
            "label": "SALES_MANAGER",
            "_link": {
                "self": "groups/2"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        },
        {
            "id": 3,
            "label": "DEVELOPMENT_MANAGER",
            "_link": {
                "self": "groups/3"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        }
    ],
    "groups_contained": [
        {
            "id": 0,
            "label": "ADMINISTRATOR",
            "_link": {
                "self": "groups/0"
            },
            "_read_only": [
                "group_container"
            ],
            "groups_container": [],
            "groups_contained": [],
            "users_system": []
        }
    ],
    "users_system": [
        {
            "id": 2,
            "username": "director",
            "_link": {
                "self": "userssystem/director"
            }
        },
        {
            "id": 10,
            "username": "director-exclude",
            "_link": {
                "self": "userssystem/director-exclude"
            }
        },
        {
            "id": 8,
            "username": "multi",
            "_link": {
                "self": "userssystem/director-exclude"
            }
        }
    ]
}

进行测试1时返回错误

{
    "code": 400,
    "message": "Validation Failed",
    "errors": {
        "children": {
            "label": {},
            "groups_contained": {
                "children": [
                    {
                        "children": {
                            "id": {}
                        }
                    }
                ]
            },
            "users_system": {
                "children": [
                    {
                        "children": {
                            "username": {
                                "errors": [
                                    "Cette valeur n'est pas valide."
                                ]
                            }
                        }
                    },
                    {
                        "children": {
                            "username": {
                                "errors": [
                                    "Cette valeur n'est pas valide."
                                ]
                            }
                        }
                    },
                    {
                        "children": {
                            "username": {
                                "errors": [
                                    "Cette valeur n'est pas valide."
                                ]
                            }
                        }
                    }
                ]
            }
        }
    }
}

进行测试2时返回错误

{
    "code": 400,
    "message": "Validation Failed",
    "errors": {
        "children": {
            "label": {},
            "groups_contained": {
                "children": [
                    {
                        "children": {
                            "id": {}
                        }
                    }
                ]
            },
            "users_system": {
                "errors": [
                    "Cette valeur n'est pas valide."
                ],
                "children": {
                    "administrator": {},
                    "director": {},
                    "sales_manager": {},
                    "development_manager": {},
                    "sales_representative": {},
                    "developer": {},
                    "employee": {},
                    "multi": {},
                    "developer-include": {},
                    "director-exclude": {},
                }
            }
        }
    }
}

0 个答案:

没有答案