mirror of
https://github.com/fzaninotto/Faker.git
synced 2025-03-22 00:09:59 +01:00
Improved Doctrine populator
* it now enables to call methods on entity wit generated arguments * added posibility of creating unique ids if they are not auto generated * added posibility to load more entities with one-to-one relationship
This commit is contained in:
parent
6d051d4c6c
commit
82f2555145
@ -17,6 +17,10 @@ class EntityPopulator
|
||||
* @var array
|
||||
*/
|
||||
protected $columnFormatters = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $modifiers = array();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
@ -51,6 +55,21 @@ class EntityPopulator
|
||||
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
|
||||
}
|
||||
|
||||
public function setModifiers(array $modifiers)
|
||||
{
|
||||
$this->modifiers = $modifiers;
|
||||
}
|
||||
|
||||
public function getModifiers()
|
||||
{
|
||||
return $this->modifiers;
|
||||
}
|
||||
|
||||
public function mergeModifiersWith(array $modifiers)
|
||||
{
|
||||
$this->modifiers = array_merge($this->modifiers, $modifiers);
|
||||
}
|
||||
|
||||
public function guessColumnFormatters(\Faker\Generator $generator)
|
||||
{
|
||||
$formatters = array();
|
||||
@ -78,7 +97,27 @@ class EntityPopulator
|
||||
}
|
||||
|
||||
$relatedClass = $this->class->getAssociationTargetClass($assocName);
|
||||
$formatters[$assocName] = function($inserted) use ($relatedClass) { return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null; };
|
||||
|
||||
$unique = false;
|
||||
$mappings = $this->class->getAssociationMappings();
|
||||
foreach ($mappings as $mapping) {
|
||||
if ($mapping['targetEntity'] == $relatedClass) {
|
||||
if ($mapping['type'] == ClassMetadata::ONE_TO_ONE) {
|
||||
$unique = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$index = 0;
|
||||
$formatters[$assocName] = function($inserted) use ($relatedClass, &$index, $unique) {
|
||||
if ($unique && isset($inserted[$relatedClass])) {
|
||||
return $inserted[$relatedClass][$index++];
|
||||
} else if (isset($inserted[$relatedClass])) {
|
||||
return $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
return $formatters;
|
||||
@ -87,18 +126,18 @@ class EntityPopulator
|
||||
/**
|
||||
* Insert one new record using the Entity class.
|
||||
*/
|
||||
public function execute($manager, $insertedEntities)
|
||||
public function execute($manager, $insertedEntities, $generateId = false)
|
||||
{
|
||||
$obj = $this->class->newInstance();
|
||||
|
||||
foreach ($this->columnFormatters as $field => $format) {
|
||||
if (null !== $format) {
|
||||
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
|
||||
if (is_callable(array($obj, $field))) {
|
||||
$obj->$field($value);
|
||||
} else {
|
||||
$this->class->reflFields[$field]->setValue($obj, $value);
|
||||
}
|
||||
$this->fillColumns($obj, $insertedEntities);
|
||||
$this->callMethods($obj, $insertedEntities);
|
||||
|
||||
if ($generateId) {
|
||||
$idsName = $this->class->getIdentifier();
|
||||
foreach ($idsName as $idName) {
|
||||
$id = $this->generateId($obj, $idName, $manager);
|
||||
$this->class->reflFields[$idName]->setValue($obj, $id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,4 +146,42 @@ class EntityPopulator
|
||||
return $obj;
|
||||
}
|
||||
|
||||
private function fillColumns($obj, $insertedEntities)
|
||||
{
|
||||
foreach ($this->columnFormatters as $field => $format) {
|
||||
if (null !== $format) {
|
||||
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
|
||||
$this->class->reflFields[$field]->setValue($obj, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function callMethods($obj, $insertedEntities)
|
||||
{
|
||||
foreach ($this->getModifiers() as $method => $formats) {
|
||||
$args = array();
|
||||
foreach ($formats as $format) {
|
||||
$args[] = is_callable($format) ? $format($insertedEntities, $obj) : $format;
|
||||
}
|
||||
call_user_func_array(array($obj, $method), $args);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateId($obj, $column, $manager)
|
||||
{
|
||||
/* @var $repository \Doctrine\ORM\EntityRepository */
|
||||
$repository = $manager->getRepository(get_class($obj));
|
||||
$result = $repository->createQueryBuilder('e')
|
||||
->select(sprintf('e.%s', $column))
|
||||
->getQuery()
|
||||
->getResult();
|
||||
$ids = array_map('current', $result);
|
||||
|
||||
$id = null;
|
||||
do {
|
||||
$id = rand();
|
||||
} while(in_array($id, $ids));
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ class Populator
|
||||
protected $manager;
|
||||
protected $entities = array();
|
||||
protected $quantities = array();
|
||||
protected $generateId = array();
|
||||
|
||||
public function __construct(\Faker\Generator $generator, ObjectManager $manager = null)
|
||||
{
|
||||
@ -27,7 +28,7 @@ class Populator
|
||||
* @param mixed $entity A Doctrine classname, or a \Faker\ORM\Doctrine\EntityPopulator instance
|
||||
* @param int $number The number of entities to populate
|
||||
*/
|
||||
public function addEntity($entity, $number, $customColumnFormatters = array())
|
||||
public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array(), $generateId = false)
|
||||
{
|
||||
if (!$entity instanceof \Faker\ORM\Doctrine\EntityPopulator) {
|
||||
$entity = new \Faker\ORM\Doctrine\EntityPopulator($this->manager->getClassMetadata($entity));
|
||||
@ -36,6 +37,9 @@ class Populator
|
||||
if ($customColumnFormatters) {
|
||||
$entity->mergeColumnFormattersWith($customColumnFormatters);
|
||||
}
|
||||
$entity->mergeModifiersWith($customModifiers);
|
||||
$this->generateId[$entity->getClass()] = $generateId;
|
||||
|
||||
$class = $entity->getClass();
|
||||
$this->entities[$class] = $entity;
|
||||
$this->quantities[$class] = $number;
|
||||
@ -59,8 +63,9 @@ class Populator
|
||||
|
||||
$insertedEntities = array();
|
||||
foreach ($this->quantities as $class => $number) {
|
||||
$generateId = $this->generateId[$class];
|
||||
for ($i=0; $i < $number; $i++) {
|
||||
$insertedEntities[$class][]= $this->entities[$class]->execute($entityManager, $insertedEntities);
|
||||
$insertedEntities[$class][]= $this->entities[$class]->execute($entityManager, $insertedEntities, $generateId);
|
||||
}
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user