只是想知道是否可以只使用symfony表单处理的某些部分。例如,当通过generate:doctrine:crud
创建CRUD操作时,我在控制器中得到如下内容(用于处理创建用户POST请求):
$entity = new User();
$form = $this->createForm(new UserType(), $entity,
array(
'action' => $this->generateUrl('user_create'),
'method' => 'POST',
));
$form->handleRequest($request);
//Here I have a filled Entity
但我想要的是在一个更可重用的解决方案中实现这一点。目前,我的业务逻辑在一个名为UserModel
的服务中。在这里,我还希望使用create
方法来创建、验证和持久化一个新实体。很难,UserModel
也应该可以通过控制台从一些命令脚本中调用,所以我可能不会总是有Request
或Form
。
因此,从上面的代码中,我知道Symfony已经在根据UserType
的定义以某种方式将数据填充到实体中,但如果没有Form
或Request
,而只是一些数据数组,我怎么能手动做到这一点呢
这样我就不必自己设置属性了。
编辑:验证对于填充实体来说没有问题,我稍后将在持久化数据之前对已填充的实体使用validator
对我来说同样重要的是,传递的related entity ids
将被自动处理/加载。
您仍然可以使用Form组件,但不应该使用handleRequest
,而应该直接使用submit
。
如果你很好奇,你应该在github上查找handleRequest
的代码以及它的实际功能;你会看到它只是做了一些验证,从Request
中获取数据,然后使用Form.的submit
方法
因此,基本上,您只能对想要使用的数据使用submit
方法。它甚至会验证您的实体。:)
更新
对于创建/更新相关实体的问题,如果你的关系有一个持久化/更新级联,它应该在你不做任何事情的情况下从自身展开,除了在你的主实体上持久化+刷新。
如果您不担心像处理验证之类的事情,您可以做一些像我所做的事情。
您可以定义一个特征,或者在实体类中包含fromArray函数。
trait EntityHydrationMethod
{
public function fromArray($data = array())
{
foreach ($data as $property => $value) {
$method = "set{$property}";
$this->$method($value);
}
}
}
如果你定义了trait,你可以在你的实体中使用它,比如:
class User{
use EntityHydrationMethod;
}
然后从你的用户模型中,你可以定义你的创建功能,比如:
public function create($data = array())
{
$entity = new User();
$entity->fromArray($data);
return $entity;
}
-已更新-
当你更新你的问题时。您可以通过定义一个trait或在EntityRepository类中包含createFromArray函数来实现这一点。
trait RepositoryCreateMethod {
public function createFromArray($data)
{
$class = $this->getClassName();
$object = new $class();
$meta = $this->getClassMetadata();
foreach ($data as $property => $value) {
$v = $value;
if(!empty($value) && $meta->hasAssociation($property)) {
$map = $meta->getAssociationMapping($property);
$v = $this->_em->getRepository($map['targetEntity'])->find($value);
if(empty($v)){
throw new 'Exception('Associate data not found');
}
}
$method = "set{$property}";
$object->$method($v);
}
return $object;
}
}
如果你定义了trait,你可以在你的存储库中使用它,比如:
class UserRepository{
use RepositoryCreateMethod;
}
然后你可以使用类似于来自控制器的调用:
$user = $this->getDoctrine()
->getRepository('YourBundle:User')
->createFromArray($data);