【发布时间】:2018-01-17 09:22:59
【问题描述】:
我没有找到任何与我的问题相关的主题,而且我的情况非常特殊,这就是我寻求帮助的原因。
我有 4 个相关实体:PurchaseOrder、SapPO、项目和产品。如下所示,PurchaseOrder 和 SapPo 之间是一对多关联,SapPo 和 Project 之间是一对多双向关联,purchaseOrder 和产品之间是多对多关联。
PurchaseOder.php:
/**
* @ORM\ManyToMany(targetEntity="SapPo",cascade={"persist","remove"})
* @ORM\JoinTable(name="po_sappo",
* joinColumns={@ORM\JoinColumn(name="po_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="sappo_id", referencedColumnName="id", unique=true,onDelete="CASCADE")}
* )
*/
private $sapPo;
/**
* @ORM\ManyToMany(targetEntity="Product", mappedBy="purchaseOrders")
*/
private $products;
SapPo.php
/**
* @ORM\ManyToOne(targetEntity="Project", inversedBy="sapPos")
* @ORM\JoinColumn(name="project_sap", referencedColumnName="id")
*/
private $project ;
项目.php:
/**
* @ORM\OneToMany(targetEntity="SapPo", mappedBy="project")
*/
private $sapPos ;
/**
* @ORM\ManyToMany(targetEntity="Product", inversedBy="projet")
* @ORM\JoinTable(name="product_project")
*/
private $products;
最后是 Product.php:
/**
* @ORM\ManyToMany(targetEntity="PurchaseOrder", inversedBy="products",
cascade={"persist"})
* @ORM\JoinTable(name="purchaseOrders_products")
*/
private $purchaseOrders;
/**
* @ORM\ManyToMany(targetEntity="Project", mappedBy="products")
*/
private $projet;
我想要做的是用代表所选项目数据之间交集的产品填充表单。 例如,我们必须选择项目 "Project 1",它有两个产品 "product 1" 和 "product 2" 和另一个项目 "project 2" 有两个产品 "product 2" 和 "product 3"。
在此示例中,“product 2” 是交集,需要用它填充表单。
使用下面显示的代码并使用 FormEvents,我已经成功地使用必要的 AJAX 调用和之后的 ArrayCollection 过滤器填充了必要的数据。问题是,一旦我提交表单,我就没有选择产品,但我得到一个空的 ArrayCollection。
PurchaseOrderType.php:
/**
* Product modifier used to modify products after the SAP PO choice validation
* @param FormInterface $form
* @param $sapPos
*/
$productModifier = function (FormInterface $form, $names){
$form->add('products', EntityType::class,array(
'class' => 'FollowupBundle:Product',
'multiple' => true,
'expanded' => false,
'query_builder' => function(EntityRepository $er) use ($names) {
$qb = $er->createQueryBuilder('u') ;
$qb->where("u.name IN (:projects)")
->setParameter('projects',$names) ;
return $qb ;
},
'choice_label' => 'name',
'placeholder' => 'Selectionner le produit'
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$sapPos = $data->getSapPo();
$form->add('products',EntityType::class,array(
'class' => 'FollowupBundle:Product',
'multiple' => true,
'expanded' => false,
'required' => false,
'choices' => [],
'placeholder' => 'selectionner les produits',
'choice_label' => 'name'
)) ;
}) ;
$builder->get('sapPo')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($productModifier){
$sapPos = $event->getForm()->getData() ;
$namesList = $this->getNamesFromSapPo($sapPos) ;
$productModifier($event->getForm()->getParent(), $namesList);
},900
) ;
编辑
这是用于过滤和提取要在查询生成器中使用的产品名称的函数。
/**
* @param Product $product
* @param ArrayCollection $sapPos
* @return bool
*/
public function filterProducts(Product $product, $sapPos){
$isCommon = true ;
foreach ($sapPos as $sapPo){
if (!$sapPo->getProject()->getProducts()->contains($product)){
$isCommon = false;
}else {
}
}
return $isCommon;
}
public function getNamesFromSapPo($sapPos){
$primilnaryProducts = new ArrayCollection() ;
$lastProducts = new ArrayCollection() ;
$namesList = [] ;
foreach ($sapPos as $sapPo){
foreach ($sapPo->getProject()->getProducts() as $product){
$primilnaryProducts->add($product) ;
}
}
// filter products
$lastProducts = $primilnaryProducts->filter(
function ($entry) use ($sapPos){
return $this->filterProducts($entry,$sapPos) ;
}
) ;
//get Names
foreach ($lastProducts as $product){
$namesList[] = $product->getName() ;
}
return $namesList ;
}
欢迎任何提示或技术建议!谢谢。
【问题讨论】:
-
正如我从
https://symfony.com/doc/current/reference/forms/types/entity.html#choices看到的(我记得):您的'choices' => []将覆盖字段中的任何数据 -
谢谢!问题是我忘记在 POST_SUBMIT 函数中使用表单修饰符了。
-
太棒了。你找到了解决方案。顺便说一句,在处理表单事件时进行更多调试 - 是找出所有问题的最佳方法,当然,如果您不经常编写它们。
-
我通常使用 PSR/Logger,但遗憾的是我无法像在 Java 中那样记录对象。
-
您可以在记录对象之前尝试对其进行序列化。而且,imo,日志记录并不是最好的调试方式 - 尝试使用 xdebug,它会更好。
标签: php forms symfony symfony-3.2