从数据数组中填充实体而不使用表单/请求

时间:2014-04-11 07:08:48

标签: php symfony

只是想知道是否可以只使用symfony表单处理的某些部分。例如,在通过generate:doctrine:crud创建CRUD操作时,我在Controller中获得了一些内容(用于处理创建用户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也应该可以通过控制台从一些命令脚本中调用,所以我可能永远不会有RequestForm

所以现在从上面的代码中我知道Symfony已经按照UserType定义以某种方式将数据填充到实体,但是如果没有Form或{{}我怎么能这样做呢? 1}}而只是一些数据? 因此,我不必自己设置属性。

修改 对于填充实体,验证不是问题,我将在以后对填充的实体使用Request之前保留数据。
对我来说同样重要的是,将自动处理/加载传递的validator

2 个答案:

答案 0 :(得分:4)

您仍然可以使用表单组件,但不应使用handleRequest,而应直接使用submit

如果你很好奇,你应该在github上查找handleRequestwhat it actually does的代码;您会看到它只是进行一些验证,从表格的Requestthen uses the submit method获取数据。

因此,基本上,您只能将submit方法与您希望使用的数据一起使用。它甚至可以验证您的实体。 :)

<强>更新

关于创建/更新相关实体的问题,如果你的关系有一个持久/更新级联,那么它应该从你自己推出而不用你做一件事,除了你的主实体上的persist + flush。

答案 1 :(得分:1)

如果您不担心处理类似事情的验证,您可以像我一样做。

您可以在实体类中定义特征或包含 fromArray 函数。

trait EntityHydrationMethod
{
    public function fromArray($data = array())
    {
        foreach ($data as $property => $value) {
            $method = "set{$property}";
            $this->$method($value);
        }
    }
}

如果您定义了特质,则可以在以下实体中使用它:

class User{

  use EntityHydrationMethod;

}

然后,从您的用户模型中,您可以定义您的创建功能,如:

public function create($data = array())
{
    $entity = new User();
    $entity->fromArray($data);
    return $entity;
}

- 更新 -

当您更新问题时。您可以通过定义特征或在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,你可以在你的Repository中使用它,如:

class UserRepository{

  use RepositoryCreateMethod;

}

然后你可以使用这个来自控制器的调用:

$user = $this->getDoctrine()
             ->getRepository('YourBundle:User')
             ->createFromArray($data);