| Current Path : /var/www/html/setup/src/Magento/Setup/Model/FixtureGenerator/ |
| Current File : /var/www/html/setup/src/Magento/Setup/Model/FixtureGenerator/BundleProductGenerator.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Setup\Model\FixtureGenerator;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
/**
* Generate specified amount of bundle products based on passed fixture
*
* See ProductGenerator for fixture arguments
* Fixture must return some specific options for generate bundle product:
* [
* '_bundle_variation_sku_pattern' => simple product sku pattern, which will be used as configurable variation,
* '_bundle_options' => amount of options per bundle product,
* '_bundle_products_per_option' => amount of simple products per each option,
* ]
* @see ProductGenerator
* @see BundleProductTemplateGenerator
*/
class BundleProductGenerator
{
/**
* @var array
*/
private $sequenceValues = [
'sequence_product_bundle_option' => null,
'sequence_product_bundle_selection' => null
];
/**
* @var ProductGeneratorFactory
*/
private $productGeneratorFactory;
/**
* @var ResourceConnection
*/
private $resource;
/**
* @param ProductGeneratorFactory $productGeneratorFactory
* @param ResourceConnection $resource|null
*/
public function __construct(
ProductGeneratorFactory $productGeneratorFactory,
ResourceConnection $resource = null
) {
$this->productGeneratorFactory = $productGeneratorFactory;
$this->resource = $resource ?: ObjectManager::getInstance()->get(
ResourceConnection::class
);
}
/**
* Generates bundle products.
*
* @param int $products
* @param array $fixtureMap
*
* @return void
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function generate($products, $fixtureMap)
{
$this->productGeneratorFactory->create([
'customTableMap' => [
'catalog_product_bundle_option' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['option_id'] = $this->generateOptionId(
$entityNumber,
$bind['option_id'],
$fixture
);
$bind['parent_id'] = $productId;
}
return $binds;
},
],
'sequence_product_bundle_option' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['sequence_value'] = $this->generateSequenceId(
'sequence_product_bundle_option'
);
}
return $binds;
},
],
'catalog_product_bundle_option_value' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['option_id'] = $this->generateOptionId(
$entityNumber,
$bind['option_id'],
$fixture
);
$bind['parent_product_id'] = $productId;
}
return $binds;
},
],
'catalog_product_bundle_selection' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['selection_id'] = $this->generateSelectionId(
$entityNumber,
$bind['selection_id'],
$fixture
);
$bind['parent_product_id'] = $productId;
$bind['option_id'] = $this->generateOptionId(
$entityNumber,
$bind['option_id'],
$fixture
);
$bind['product_id'] = $this->generateSimpleProductId(
$bind['product_id'],
$entityNumber,
$fixture
);
$bind['selection_price_type'] = $fixture['priceType']($bind['product_id']);
$bind['selection_price_value'] = $fixture['price']($bind['product_id']);
}
return $binds;
},
],
'sequence_product_bundle_selection' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['sequence_value'] = $this->generateSequenceId(
'sequence_product_bundle_selection'
);
}
return $binds;
},
],
'catalog_product_relation' => [
'entity_id_field' => EntityGenerator::SKIP_ENTITY_ID_BINDING,
'handler' => function ($productId, $entityNumber, $fixture, $binds) {
foreach ($binds as &$bind) {
$bind['parent_id'] = $productId;
$bind['child_id'] = $this->generateSimpleProductId(
$bind['child_id'],
$entityNumber,
$fixture
);
}
return $binds;
},
],
]
])->generate($products, $fixtureMap);
}
/**
* Generates an option Id.
*
* @param int $entityNumber
* @param int $originalOptionId
* @param array $fixture
*
* @return int|null
*/
private function generateOptionId($entityNumber, $originalOptionId, array $fixture)
{
if ($originalOptionId) {
return $fixture['_bundle_options'] * ($entityNumber + 1) + $originalOptionId;
}
return $originalOptionId;
}
/**
* Generates a selection Id.
*
* @param int $entityNumber
* @param int $originalSelectionId
* @param array $fixture
*
* @return int|null
*/
private function generateSelectionId($entityNumber, $originalSelectionId, array $fixture)
{
if ($originalSelectionId) {
$selectionsPerProduct = $fixture['_bundle_products_per_option'] * $fixture['_bundle_options'];
return $selectionsPerProduct * ($entityNumber + 1) + $originalSelectionId;
}
return $originalSelectionId;
}
/**
* Generates an Id for the given sequence table.
*
* @param string $tableName
*
* @return int
*/
private function generateSequenceId($tableName)
{
if (!$this->sequenceValues[$tableName]) {
$connection = $this->resource->getConnection();
$this->sequenceValues[$tableName] = $connection->fetchOne(
$connection->select()->from(
$this->resource->getTableName($tableName),
'MAX(`sequence_value`)'
)
);
}
return ++$this->sequenceValues[$tableName];
}
/**
* Generate value of simple product id which is used for $entityNumber bundle product as option item
*
* @param int $previousProductId
* @param int $entityNumber
* @param array $fixture
* @return mixed
*/
private function generateSimpleProductId($previousProductId, $entityNumber, array $fixture)
{
return $previousProductId +
$entityNumber * $fixture['_bundle_products_per_option'] * $fixture['_bundle_options'];
}
}