如何映射 Product 实体,使其由 Doctrine 管理?
How to map Product entity so that it is managed by Doctrine?
我正在尝试在 PS 1.7.6.1.
下构建一个模块
在设计中,我在 Product 和 Preorder 之间有一个多对一的关系(许多预购可以关联到一个产品)。
Preorder 对象是一个 ORM 实体:
//mymodule/src/Entity
class Preorder
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_preorder", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product", type="integer")
*/
private $productId;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=64)
*/
private $email;
setter and getter
}
在控制器中:
//src/mymodule/src/Controller
use Doctrine\DBAL\Types\TextType;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Doctrine\ORM\EntityManagerInterface;
use MyModule\Entity\Preoder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\HttpFoundation\Request;
use Product;
class PreorderController extends FrameworkBundleAdminController
{
public function createAction(Request $request){
$preorder = new Preorder();
$preorderForm = $this->createFormBuilder($preorder)
->add('email', EmailType::class)
->add('productId', EntityType::class, [
'class' => Product::class,
])
->getForm();
$bookingForm->handleRequest($request);
// validate and persist
}}
问题是表单生成器无法识别产品实体。它抛出运行时异常:
Class "Product" seems not to be a managed Doctrine entity. Did you
forget to map it?
我在核心文件中找不到处理这种情况的示例。提前非常感谢 guiding/helping 我解决了这个问题。
主要问题是 product_id
不是实体,因此 formbuilder
使用 EntityType::class
处理它的可能性为 0。您需要正确定义(如 doc 中所述)您与对象的 ManyToOne 关系
在产品方面:
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
// usual stuff
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="product", cascade={"persist"})
*/
private $preorders;
}
在预订方面:
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
// usual stuff
/**
* @ORM\OneToMany(targetEntity="App\Entity\Product", mappedBy="preorders")
*/
private $product;
}
在您的 formBuilder 中,product
将是一个 entity
并被 EntityType::class
识别
编辑
如果您的 product
是 ORM 未映射的遗留 class,那么您可以使用 dataTransformer 来帮助您的 formBuilder 识别遗留实体。
namespace App\DataTransformer;
class ProductToIdTransformer implements DataTransformerInterface
{
public function transform($product)
{
if (null === $product) {
return '';
}
return $product->getId();
}
public function reverseTransform($product_id)
{
if (!$product_id){
return;
}
//your db logic to retrieve the product
if (null === $field){
throw new TransformationFailedException(sprintf("the product '%s' does not exist!", $product_id));
}
return $product;
}
}
然后在您的表单生成器中,您将使用 CollectionType
代替:
$preorderForm = $this->createFormBuilder($preorder)
->add('email', EmailType::class)
->add('product', CollectionType::class, [
'class' => Product::class,
//some logic to adapt the different choices to your needs
])
;
$preorderForm
->get('product')
->addModelTransformer(ProductToIdTransformer::class)
;
$preorderForm = $preorderForm->getForm();
我正在尝试在 PS 1.7.6.1.
下构建一个模块在设计中,我在 Product 和 Preorder 之间有一个多对一的关系(许多预购可以关联到一个产品)。
Preorder 对象是一个 ORM 实体:
//mymodule/src/Entity
class Preorder
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id_preorder", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="id_product", type="integer")
*/
private $productId;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=64)
*/
private $email;
setter and getter
}
在控制器中:
//src/mymodule/src/Controller
use Doctrine\DBAL\Types\TextType;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Doctrine\ORM\EntityManagerInterface;
use MyModule\Entity\Preoder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\HttpFoundation\Request;
use Product;
class PreorderController extends FrameworkBundleAdminController
{
public function createAction(Request $request){
$preorder = new Preorder();
$preorderForm = $this->createFormBuilder($preorder)
->add('email', EmailType::class)
->add('productId', EntityType::class, [
'class' => Product::class,
])
->getForm();
$bookingForm->handleRequest($request);
// validate and persist
}}
问题是表单生成器无法识别产品实体。它抛出运行时异常:
Class "Product" seems not to be a managed Doctrine entity. Did you forget to map it?
我在核心文件中找不到处理这种情况的示例。提前非常感谢 guiding/helping 我解决了这个问题。
主要问题是 product_id
不是实体,因此 formbuilder
使用 EntityType::class
处理它的可能性为 0。您需要正确定义(如 doc 中所述)您与对象的 ManyToOne 关系
在产品方面:
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
// usual stuff
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="product", cascade={"persist"})
*/
private $preorders;
}
在预订方面:
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
*/
class Product
{
// usual stuff
/**
* @ORM\OneToMany(targetEntity="App\Entity\Product", mappedBy="preorders")
*/
private $product;
}
在您的 formBuilder 中,product
将是一个 entity
并被 EntityType::class
编辑
如果您的 product
是 ORM 未映射的遗留 class,那么您可以使用 dataTransformer 来帮助您的 formBuilder 识别遗留实体。
namespace App\DataTransformer;
class ProductToIdTransformer implements DataTransformerInterface
{
public function transform($product)
{
if (null === $product) {
return '';
}
return $product->getId();
}
public function reverseTransform($product_id)
{
if (!$product_id){
return;
}
//your db logic to retrieve the product
if (null === $field){
throw new TransformationFailedException(sprintf("the product '%s' does not exist!", $product_id));
}
return $product;
}
}
然后在您的表单生成器中,您将使用 CollectionType
代替:
$preorderForm = $this->createFormBuilder($preorder)
->add('email', EmailType::class)
->add('product', CollectionType::class, [
'class' => Product::class,
//some logic to adapt the different choices to your needs
])
;
$preorderForm
->get('product')
->addModelTransformer(ProductToIdTransformer::class)
;
$preorderForm = $preorderForm->getForm();