PageRenderTime 78ms CodeModel.GetById 4ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Faker/ORM/Spot/EntityPopulator.php

http://github.com/fzaninotto/Faker
PHP | 219 lines | 120 code | 29 blank | 70 comment | 9 complexity | 37f06521f12ba78de64c69058bb9ae81 MD5 | raw file
  1. <?php
  2. namespace Faker\ORM\Spot;
  3. use Faker\Generator;
  4. use Faker\Guesser\Name;
  5. use Spot\Locator;
  6. use Spot\Mapper;
  7. use Spot\Relation\BelongsTo;
  8. /**
  9. * Service class for populating a table through a Spot Entity class.
  10. */
  11. class EntityPopulator
  12. {
  13. /**
  14. * When fetching existing data - fetch only few first rows.
  15. */
  16. const RELATED_FETCH_COUNT = 10;
  17. /**
  18. * @var Mapper
  19. */
  20. protected $mapper;
  21. /**
  22. * @var Locator
  23. */
  24. protected $locator;
  25. /**
  26. * @var array
  27. */
  28. protected $columnFormatters = array();
  29. /**
  30. * @var array
  31. */
  32. protected $modifiers = array();
  33. /**
  34. * @var bool
  35. */
  36. protected $useExistingData = false;
  37. /**
  38. * Class constructor.
  39. *
  40. * @param Mapper $mapper
  41. * @param Locator $locator
  42. * @param $useExistingData
  43. */
  44. public function __construct(Mapper $mapper, Locator $locator, $useExistingData = false)
  45. {
  46. $this->mapper = $mapper;
  47. $this->locator = $locator;
  48. $this->useExistingData = $useExistingData;
  49. }
  50. /**
  51. * @return string
  52. */
  53. public function getMapper()
  54. {
  55. return $this->mapper;
  56. }
  57. /**
  58. * @param $columnFormatters
  59. */
  60. public function setColumnFormatters($columnFormatters)
  61. {
  62. $this->columnFormatters = $columnFormatters;
  63. }
  64. /**
  65. * @return array
  66. */
  67. public function getColumnFormatters()
  68. {
  69. return $this->columnFormatters;
  70. }
  71. /**
  72. * @param $columnFormatters
  73. */
  74. public function mergeColumnFormattersWith($columnFormatters)
  75. {
  76. $this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
  77. }
  78. /**
  79. * @param array $modifiers
  80. */
  81. public function setModifiers(array $modifiers)
  82. {
  83. $this->modifiers = $modifiers;
  84. }
  85. /**
  86. * @return array
  87. */
  88. public function getModifiers()
  89. {
  90. return $this->modifiers;
  91. }
  92. /**
  93. * @param array $modifiers
  94. */
  95. public function mergeModifiersWith(array $modifiers)
  96. {
  97. $this->modifiers = array_merge($this->modifiers, $modifiers);
  98. }
  99. /**
  100. * @param Generator $generator
  101. * @return array
  102. */
  103. public function guessColumnFormatters(Generator $generator)
  104. {
  105. $formatters = array();
  106. $nameGuesser = new Name($generator);
  107. $columnTypeGuesser = new ColumnTypeGuesser($generator);
  108. $fields = $this->mapper->fields();
  109. foreach ($fields as $fieldName => $field) {
  110. if ($field['primary'] === true) {
  111. continue;
  112. }
  113. if ($formatter = $nameGuesser->guessFormat($fieldName)) {
  114. $formatters[$fieldName] = $formatter;
  115. continue;
  116. }
  117. if ($formatter = $columnTypeGuesser->guessFormat($field)) {
  118. $formatters[$fieldName] = $formatter;
  119. continue;
  120. }
  121. }
  122. $entityName = $this->mapper->entity();
  123. $entity = $this->mapper->build([]);
  124. $relations = $entityName::relations($this->mapper, $entity);
  125. foreach ($relations as $relation) {
  126. // We don't need any other relation here.
  127. if ($relation instanceof BelongsTo) {
  128. $fieldName = $relation->localKey();
  129. $entityName = $relation->entityName();
  130. $field = $fields[$fieldName];
  131. $required = $field['required'];
  132. $locator = $this->locator;
  133. $formatters[$fieldName] = function ($inserted) use ($required, $entityName, $locator) {
  134. if (!empty($inserted[$entityName])) {
  135. return $inserted[$entityName][mt_rand(0, count($inserted[$entityName]) - 1)]->get('id');
  136. }
  137. if ($required && $this->useExistingData) {
  138. // We did not add anything like this, but it's required,
  139. // So let's find something existing in DB.
  140. $mapper = $locator->mapper($entityName);
  141. $records = $mapper->all()->limit(self::RELATED_FETCH_COUNT)->toArray();
  142. if (empty($records)) {
  143. return null;
  144. }
  145. return $records[mt_rand(0, count($records) - 1)]['id'];
  146. }
  147. return null;
  148. };
  149. }
  150. }
  151. return $formatters;
  152. }
  153. /**
  154. * Insert one new record using the Entity class.
  155. *
  156. * @param $insertedEntities
  157. * @return string
  158. */
  159. public function execute($insertedEntities)
  160. {
  161. $obj = $this->mapper->build([]);
  162. $this->fillColumns($obj, $insertedEntities);
  163. $this->callMethods($obj, $insertedEntities);
  164. $this->mapper->insert($obj);
  165. return $obj;
  166. }
  167. /**
  168. * @param $obj
  169. * @param $insertedEntities
  170. */
  171. private function fillColumns($obj, $insertedEntities)
  172. {
  173. foreach ($this->columnFormatters as $field => $format) {
  174. if (null !== $format) {
  175. $value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
  176. $obj->set($field, $value);
  177. }
  178. }
  179. }
  180. /**
  181. * @param $obj
  182. * @param $insertedEntities
  183. */
  184. private function callMethods($obj, $insertedEntities)
  185. {
  186. foreach ($this->getModifiers() as $modifier) {
  187. $modifier($obj, $insertedEntities);
  188. }
  189. }
  190. }