Reputation: 2206
I am looking for a way to convert an array to doctrine Entity. I am using doctrine 2.
I have an entity class like:
class User
{
/**
* @Id
* @Column(type="integer", nullable=false)
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255, unique=true, nullable=false)
*/
protected $email;
/**
* @Column(type="string", length=64, nullable=false)
*/
protected $password;
/**
* @var DateTime
* @Column(type="datetime", nullable=false)
*/
protected $dob;
//getter and setters
}
When I post data from a html form, I want to convert the post array to the User entity. So I have an array like
$userAsArray = array("email"=>"[email protected]","password"=>"hello","dob"=>"10\20\1990");
$user = new User();
covert($userAsArray,$user) // I am looking for something like this
I am looking for a generic way to accomplish this. I have tried something like this:
function fromArray(array $array,$class){
$user = new $class();
foreach($array as $key => $field){
$keyUp = ucfirst($key);
if(method_exists($user,'set'.$keyUp)){
call_user_func(array($user,'set'.$keyUp),$field);
}
}
return $user;
}
But the problem is it sets everything as string. But for the date I want to have it as a DateTime object. Any help?
Upvotes: 2
Views: 10722
Reputation: 9857
You are trying to de-serialize
I would check out the Zend Framework 2 Stdlib component. You do not need to use the whole framework.
The Hydrators, specifically the DoctrineModule\Stdlib\Hydrator\DoctrineObject, do what you are asking.
Upvotes: 0
Reputation: 8840
what if one of your array elements is a foreign key ? before setting entity properties, you might need to prepare foreign key attributes. This is how I accomplish similar task:
Extend Repository
<?php
namespace My\Doctrine;
use Doctrine\ORM\EntityRepository;
class Repository extends EntityRepository
{
/**
* Prepare attributes for entity
* replace foreign keys with entity instances
*
* @param array $attributes entity attributes
* @return array modified attributes values
*/
public function prepareAttributes(array $attributes)
{
foreach ($attributes as $fieldName => &$fieldValue) {
if (!$this->getClassMetadata()->hasAssociation($fieldName)) {
continue;
}
$association = $this->getClassMetadata()
->getAssociationMapping($fieldName);
if (is_null($fieldValue)) {
continue;
}
$fieldValue = $this->getEntityManager()
->getReference($association['targetEntity'], $fieldValue);
unset($fieldValue);
}
return $attributes;
}
}
Create parent Entity
class :
namespace My\Doctrine;
class Entity
{
/**
* Assign entity properties using an array
*
* @param array $attributes assoc array of values to assign
* @return null
*/
public function fromArray(array $attributes)
{
foreach ($attributes as $name => $value) {
if (property_exists($this, $name)) {
$methodName = $this->_getSetterName($name);
if ($methodName) {
$this->{$methodName}($value);
} else {
$this->$name = $value;
}
}
}
}
/**
* Get property setter method name (if exists)
*
* @param string $propertyName entity property name
* @return false|string
*/
protected function _getSetterName($propertyName)
{
$prefixes = array('add', 'set');
foreach ($prefixes as $prefix) {
$methodName = sprintf('%s%s', $prefix, ucfirst(strtolower($propertyName)));
if (method_exists($this, $methodName)) {
return $methodName;
}
}
return false;
}
}
Usage, a method in your repo:
$entity = new User();
$attributes = array(
"email" =>"[email protected]",
"password" =>"hello",
"dob" =>"10\20\1990"));
$entity->fromArray($this->prepareAttributes($attributes));
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush();
Upvotes: 6
Reputation: 164970
Why not write your setDob()
method to detect a string and convert it if necessary
public function setDob($dob) {
if (!$dob instanceof DateTime) {
$dob = new DateTime((string) $dob); // or however you want to do the conversion
}
$this->dob = $dob;
}
Upvotes: 1