PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Faker/ORM/Doctrine/EntityPopulator.php

https://github.com/gobb/Faker
PHP | 184 lines | 132 code | 28 blank | 24 comment | 15 complexity | fe8042018bacfbcd78e76a3dadc3a83a MD5 | raw file
  1. <?php
  2. namespace Faker\ORM\Doctrine;
  3. use Doctrine\ORM\Mapping\ClassMetadata;
  4. use Faker\ORM\Doctrine\ColumnTypeGuesser;
  5. /**
  6. * Service class for populating a table through a Propel ActiveRecord class.
  7. */
  8. class EntityPopulator
  9. {
  10. /**
  11. * @var ClassMetadata
  12. */
  13. protected $class;
  14. /**
  15. * @var array
  16. */
  17. protected $columnFormatters = array();
  18. /**
  19. * @var array
  20. */
  21. protected $modifiers = array();
  22. /**
  23. * Class constructor.
  24. *
  25. * @param ClassMetadata $class
  26. */
  27. public function __construct(ClassMetadata $class)
  28. {
  29. $this->class = $class;
  30. }
  31. /**
  32. * @return string
  33. */
  34. public function getClass()
  35. {
  36. return $this->class->getName();
  37. }
  38. public function setColumnFormatters($columnFormatters)
  39. {
  40. $this->columnFormatters = $columnFormatters;
  41. }
  42. public function getColumnFormatters()
  43. {
  44. return $this->columnFormatters;
  45. }
  46. public function mergeColumnFormattersWith($columnFormatters)
  47. {
  48. $this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
  49. }
  50. public function setModifiers(array $modifiers)
  51. {
  52. $this->modifiers = $modifiers;
  53. }
  54. public function getModifiers()
  55. {
  56. return $this->modifiers;
  57. }
  58. public function mergeModifiersWith(array $modifiers)
  59. {
  60. $this->modifiers = array_merge($this->modifiers, $modifiers);
  61. }
  62. public function guessColumnFormatters(\Faker\Generator $generator)
  63. {
  64. $formatters = array();
  65. $class = $this->class;
  66. $nameGuesser = new \Faker\Guesser\Name($generator);
  67. $columnTypeGuesser = new ColumnTypeGuesser($generator);
  68. foreach ($this->class->getFieldNames() AS $fieldName) {
  69. if ($this->class->isIdentifier($fieldName) || !$this->class->hasField($fieldName)) {
  70. continue;
  71. }
  72. if ($formatter = $nameGuesser->guessFormat($fieldName)) {
  73. $formatters[$fieldName] = $formatter;
  74. continue;
  75. }
  76. if ($formatter = $columnTypeGuesser->guessFormat($fieldName, $this->class)) {
  77. $formatters[$fieldName] = $formatter;
  78. continue;
  79. }
  80. }
  81. foreach ($this->class->getAssociationNames() AS $assocName) {
  82. if ($this->class->isCollectionValuedAssociation($assocName)) {
  83. continue;
  84. }
  85. $relatedClass = $this->class->getAssociationTargetClass($assocName);
  86. $unique = false;
  87. $mappings = $this->class->getAssociationMappings();
  88. foreach ($mappings as $mapping) {
  89. if ($mapping['targetEntity'] == $relatedClass) {
  90. if ($mapping['type'] == ClassMetadata::ONE_TO_ONE) {
  91. $unique = true;
  92. break;
  93. }
  94. }
  95. }
  96. $index = 0;
  97. $formatters[$assocName] = function($inserted) use ($relatedClass, &$index, $unique) {
  98. if ($unique && isset($inserted[$relatedClass])) {
  99. return $inserted[$relatedClass][$index++];
  100. } else if (isset($inserted[$relatedClass])) {
  101. return $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)];
  102. }
  103. return null;
  104. };
  105. }
  106. return $formatters;
  107. }
  108. /**
  109. * Insert one new record using the Entity class.
  110. */
  111. public function execute($manager, $insertedEntities, $generateId = false)
  112. {
  113. $obj = $this->class->newInstance();
  114. $this->fillColumns($obj, $insertedEntities);
  115. $this->callMethods($obj, $insertedEntities);
  116. if ($generateId) {
  117. $idsName = $this->class->getIdentifier();
  118. foreach ($idsName as $idName) {
  119. $id = $this->generateId($obj, $idName, $manager);
  120. $this->class->reflFields[$idName]->setValue($obj, $id);
  121. }
  122. }
  123. $manager->persist($obj);
  124. return $obj;
  125. }
  126. private function fillColumns($obj, $insertedEntities)
  127. {
  128. foreach ($this->columnFormatters as $field => $format) {
  129. if (null !== $format) {
  130. $value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
  131. $this->class->reflFields[$field]->setValue($obj, $value);
  132. }
  133. }
  134. }
  135. private function callMethods($obj, $insertedEntities)
  136. {
  137. foreach ($this->getModifiers() as $modifier) {
  138. $modifier($obj, $insertedEntities);
  139. }
  140. }
  141. private function generateId($obj, $column, $manager)
  142. {
  143. /* @var $repository \Doctrine\ORM\EntityRepository */
  144. $repository = $manager->getRepository(get_class($obj));
  145. $result = $repository->createQueryBuilder('e')
  146. ->select(sprintf('e.%s', $column))
  147. ->getQuery()
  148. ->getResult();
  149. $ids = array_map('current', $result);
  150. $id = null;
  151. do {
  152. $id = rand();
  153. } while(in_array($id, $ids));
  154. return $id;
  155. }
  156. }