30 private $customTableMap;
42 private $sqlCollector;
47 private $resourceConnection;
52 private $attributeLoader;
67 private $tableToEntityIdMap;
79 private $primaryEntityIdTables;
84 private $metadataPool;
89 private $entityMetadata;
94 private $sequenceRegistry;
99 private $isMappingInitialized =
false;
121 \
Magento\Framework\EntityManager\Sequence\SequenceRegistry $sequenceRegistry,
123 $customTableMap = [],
124 $bunchSize = self::SQL_DEFAULT_BUNCH_AMOUNT
126 $this->sqlCollector = $sqlCollector;
128 $this->attributeLoader = $attributeLoader;
129 $this->metadataPool = $metadataPool;
130 $this->sequenceRegistry = $sequenceRegistry;
131 $this->customTableMap = $customTableMap;
132 $this->entityType = $entityType;
133 $this->bunchSize = (int)$bunchSize;
147 $this->getConnection()->beginTransaction();
149 $this->sqlCollector->enable();
151 $this->sqlCollector->disable();
153 $this->getConnection()->commit();
155 $this->getConnection()->rollBack();
157 __(
'Cannot generate entities - error occurred during template creation: %1', $e->getMessage()),
164 $entitiesAmount = (int)$entitiesAmount;
166 for ($entityNumber = 0; $entityNumber < $entitiesAmount; $entityNumber++) {
168 $map = array_merge_recursive(
$map, $this->getSqlQueries(
$entity, $entityNumber, $fixture));
170 if ($processed % $this->bunchSize === 0 || $entityNumber === ($entitiesAmount - 1)) {
171 $this->saveEntities(
$map);
185 private function getSqlQueries(
$entity, $entityNumber, callable $fixtureMap)
187 $metadata = $this->getEntityMetadata();
188 $this->initializeMapping();
190 $entityId =
$entity->getData($metadata->getIdentifierField()) + $entityNumber;
191 $entityLinkId =
$entity->getData($metadata->getLinkField()) + $entityNumber;
192 $fixtureMap = $fixtureMap($entityId, $entityNumber);
195 foreach ($this->sqlCollector->getSql() as
$pattern) {
198 if (!isset($sql[
$table])) {
202 foreach ($binds as &$bind) {
203 if (
$table === $this->getEntityTable()) {
204 $bind[$metadata->getLinkField()] = $entityLinkId;
205 $bind[$metadata->getIdentifierField()] = $entityId;
209 $this->setNewBindValue($entityId, $entityNumber,
$table, $bind, $fixtureMap);
211 if (self::SKIP_ENTITY_ID_BINDING === $this->getEntityIdField(
$table)) {
214 if ($this->getEntityIdField(
$table) === $metadata->getLinkField()) {
215 $bind[$this->getEntityIdField(
$table)] = $entityLinkId;
217 $bind[$this->getEntityIdField(
$table)] = $entityId;
221 $binds = $this->bindWithCustomHandler(
$table, $entityId, $entityNumber, $fixtureMap, $binds);
238 private function bindWithCustomHandler(
$table, $entityId, $entityNumber, $fixtureMap, $binds)
240 if (isset($this->customTableMap[
$table][
'handler'])
241 && is_callable($this->customTableMap[
$table][
'handler'])
243 $binds = $this->customTableMap[
$table][
'handler']($entityId, $entityNumber, $fixtureMap, $binds);
256 private function saveEntities(array &
$map)
258 $this->getConnection()->beginTransaction();
261 $this->getConnection()->insertMultiple(
$table,
$data);
263 $this->getConnection()->commit();
264 }
catch (\Exception $e) {
265 $this->getConnection()->rollBack();
266 throw new LocalizedException(
267 __(
'Cannot save entity. Error occurred: %1', $e->getMessage()),
278 private function getConnection()
280 if (
null === $this->connection) {
281 $this->connection = $this->resourceConnection->getConnection();
284 return $this->connection;
290 private function getEntityMetadata()
292 if (
null === $this->entityMetadata) {
293 $this->entityMetadata = $this->metadataPool->getMetadata($this->entityType);
296 return $this->entityMetadata;
304 private function getEntityTable()
306 if (
null === $this->entityTable) {
307 $this->entityTable = $this->getEntityMetadata()->getEntityTable();
310 return $this->entityTable;
321 private function getEntityIdField(
$table)
323 if (!isset($this->tableToEntityIdMap[
$table])) {
325 foreach ($this->primaryEntityIdTables as $primaryTable) {
326 $foreignKey = array_filter(
327 $this->getConnection()->getForeignKeys(
$table),
328 function ($ddl) use ($primaryTable) {
329 return $ddl[
'REF_TABLE_NAME'] === $primaryTable
330 && $ddl[
'REF_COLUMN_NAME'] === $this->getEntityIdField($primaryTable);
338 throw new ValidatorException(
339 __(
'The entity ID field for the "%1" table wasn\'t found. Verify the field and try again.',
$table)
342 $this->tableToEntityIdMap[
$table] = current($foreignKey)[
'COLUMN_NAME'];
345 return $this->tableToEntityIdMap[
$table];
354 private function initializeMapping()
356 if (!$this->isMappingInitialized) {
357 $this->isMappingInitialized =
true;
359 $this->initCustomTables();
361 $this->primaryEntityIdTables = [
362 $this->getEntityMetadata()->getEntityTable()
364 $entitySequence = $this->sequenceRegistry->retrieve($this->entityType);
365 if (isset($entitySequence[
'sequenceTable'])) {
366 $this->primaryEntityIdTables[] = $this->resourceConnection->getTableName(
367 $entitySequence[
'sequenceTable']
371 foreach ($this->primaryEntityIdTables as
$table) {
373 $this->getConnection()->describeTable(
$table),
375 return $data[
'PRIMARY'] ===
true;
379 throw new ValidatorException(
380 __(
'The primary key for the "%1" table wasn\'t found. Verify the key and try again.',
$table)
383 $this->tableToEntityIdMap[
$table] = current($ddl)[
'COLUMN_NAME'];
393 private function initCustomTables()
396 'entity_id_field' =>
null,
400 $customTableMap = [];
401 foreach ($this->customTableMap as
$table =>
$data) {
402 $table = $this->resourceConnection->getTableName(
$table);
405 if (
$data[
'entity_id_field']) {
406 $this->tableToEntityIdMap[
$table] =
$data[
'entity_id_field'];
409 $this->customTableMap = $customTableMap;
417 private function getAttributesMetadata()
419 if (
null === $this->attributes) {
420 foreach ($this->attributeLoader->getAttributes($this->entityType) as
$attribute) {
425 'value_field' =>
'value',
426 'link_field' =>
'attribute_id',
427 'attribute_id' =>
$attribute->getAttributeId(),
432 return $this->attributes;
446 private function setNewBindValue($entityId, $entityNumber,
$table, array &$bind, array $fixtureMap)
448 $attributes = $this->getAttributesMetadata();
449 if (isset($attributes[
$table])) {
451 foreach ($fixtureMap as $fixtureField => $fixture) {
452 if (!isset($attributes[
$table][$fixtureField])) {
460 $bind[
$attribute[
'value_field']] = $this->getBindValue($fixture, $entityId, $entityNumber);
465 foreach ($this->customTableMap[
$table][
'fields'] as $field => $fixtureField) {
466 $bind[$field] = $this->getFixtureValue($fixtureField, $entityId, $entityNumber, $fixtureMap);
478 private function getFixtureValue($fixtureField, $entityId, $entityNumber, array $fixtureMap)
480 $fixture = isset($fixtureMap[$fixtureField]) ? $fixtureMap[$fixtureField] :
null;
481 return $fixture ? $this->getBindValue($fixture, $entityId, $entityNumber) :
'';
490 private function getBindValue($fixture, $entityId, $entityNumber)
492 $bindValue = is_callable($fixture)
496 return is_array($bindValue) ? array_shift($bindValue) : $bindValue;
__construct(\Magento\Setup\Model\FixtureGenerator\SqlCollector $sqlCollector, \Magento\Eav\Model\ResourceModel\AttributeLoader $attributeLoader, \Magento\Framework\App\ResourceConnection $resourceConnection, \Magento\Framework\EntityManager\MetadataPool $metadataPool, \Magento\Framework\EntityManager\Sequence\SequenceRegistry $sequenceRegistry, $entityType, $customTableMap=[], $bunchSize=self::SQL_DEFAULT_BUNCH_AMOUNT)
const SQL_DEFAULT_BUNCH_AMOUNT
elseif(isset( $params[ 'redirect_parent']))
const SKIP_ENTITY_ID_BINDING
call_user_func($callable, $param)
generate(TemplateEntityGeneratorInterface $entityGenerator, $entitiesAmount, callable $fixture)