1
0
mirror of https://github.com/fzaninotto/Faker.git synced 2025-03-23 00:39:47 +01:00

Merge pull request #105 from nenadalm/master

Possibility to call methods on entities, possibility to generate unique id
This commit is contained in:
Francois Zaninotto 2013-02-04 01:56:26 -08:00
commit 85e3754319
2 changed files with 96 additions and 9 deletions

View File

@ -2,7 +2,8 @@
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadata;
use Faker\ORM\Doctrine\ColumnTypeGuesser;
/**
* Service class for populating a table through a Propel ActiveRecord class.
@ -17,6 +18,10 @@ class EntityPopulator
* @var array
*/
protected $columnFormatters = array();
/**
* @var array
*/
protected $modifiers = array();
/**
* Class constructor.
@ -51,6 +56,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 +98,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,14 +127,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;
$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);
}
}
@ -103,4 +147,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;
}
}

View File

@ -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();
}