Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ProductGenerator.php
Go to the documentation of this file.
1 <?php
8 
13 
40 {
44  private $productFactory;
45 
49  private $categoryCollectionFactory;
50 
54  private $urlRewriteFactory;
55 
59  private $storeCollectionFactory;
60 
64  private $categories = [];
65 
69  private $storesPerWebsite = [];
70 
74  private $entityGeneratorFactory;
75 
79  private $storeManager;
80 
84  private $productTemplateGeneratorFactory;
85 
89  private $productUrlSuffix = [];
90 
94  private $scopeConfig;
95 
99  private $customTableMap;
100 
112  public function __construct(
113  \Magento\Catalog\Model\ProductFactory $productFactory,
114  \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
115  \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory,
116  \Magento\Store\Model\ResourceModel\Store\CollectionFactory $storeCollectionFactory,
117  EntityGeneratorFactory $entityGeneratorFactory,
118  \Magento\Store\Model\StoreManagerInterface $storeManager,
119  ProductTemplateGeneratorFactory $productTemplateGeneratorFactory,
120  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
121  $customTableMap = []
122  ) {
123  $this->productFactory = $productFactory;
124  $this->categoryCollectionFactory = $categoryCollectionFactory;
125  $this->urlRewriteFactory = $urlRewriteFactory;
126  $this->storeCollectionFactory = $storeCollectionFactory;
127  $this->entityGeneratorFactory = $entityGeneratorFactory;
128  $this->storeManager = $storeManager;
129  $this->productTemplateGeneratorFactory = $productTemplateGeneratorFactory;
130  $this->scopeConfig = $scopeConfig;
131  $this->customTableMap = $customTableMap;
132  }
133 
141  public function generate($products, $fixtureMap)
142  {
143  $this->initializeFixtureDefaultValues($fixtureMap);
144  $attributeSets = [];
145  // prepare attribute sets distribution for save products per attribute set
146  for ($productNumber = 1; $productNumber <= $products; $productNumber++) {
147  $attributeSetId = $this->getFixtureValue('attribute_set_id', $productNumber, $productNumber, $fixtureMap);
148  if (!isset($attributeSets[$attributeSetId])) {
149  $attributeSets[$attributeSetId] = 0;
150  }
151  $attributeSets[$attributeSetId]++;
152  }
153 
154  $customTableMap = [
155  'url_rewrite' => [
156  'entity_id_field' => 'entity_id',
157  'handler' => function ($productId, $entityNumber, $fixture) {
158  return $this->urlRewriteHandler($productId, $entityNumber, $fixture);
159  },
160  ],
161  'catalog_category_product' => [
162  'fields' => [
163  'category_id' => 'category_ids',
164  ],
165  ],
166  'catalog_product_entity' => [
167  'fields' => [
168  'attribute_set_id' => 'attribute_set_id',
169  'sku' => 'sku',
170  ],
171  ],
172  ];
173  $websiteIdsFixtures = $fixtureMap['website_ids'](1, 0);
174  if (is_array($websiteIdsFixtures) && count($websiteIdsFixtures) === 1) {
175  // Get website id from fixture in case when one site is assigned per product
176  $customTableMap['catalog_product_website'] = [
177  'fields' => [
178  'website_id' => 'website_ids',
179  ]
180  ];
181  }
182  $generator = $this->entityGeneratorFactory->create(
183  [
184  'entityType' => ProductInterface::class,
185  'customTableMap' => array_merge($customTableMap, $this->customTableMap)
186  ]
187  );
188  foreach ($attributeSets as $attributeSetId => $productsAmount) {
189  $fixtureMap = array_merge($fixtureMap, ['attribute_set_id' => $attributeSetId]);
190  $generator->generate(
191  $this->productTemplateGeneratorFactory->create($fixtureMap),
193  function ($productNumber, $entityNumber) use ($attributeSetId, $fixtureMap) {
194  // add additional attributes to fixture for fulfill it during product generation
195  return array_merge(
196  $fixtureMap,
197  $fixtureMap['additional_attributes']($attributeSetId, $productNumber, $entityNumber)
198  );
199  }
200  );
201  }
202  }
203 
208  private function initializeFixtureDefaultValues(array &$fixture)
209  {
210  $defaultValues = [
211  'attribute_set_id' => function () {
212  return $this->productFactory->create()->getDefaultAttributeSetId();
213  },
214  'additional_attributes' => function () {
215  return [];
216  },
217  'url_key' => function ($productId, $entityNumber) use ($fixture) {
218  return strtolower(str_replace(' ', '-', $fixture['sku']($productId, $entityNumber)));
219  },
220  'website_ids' => function () {
221  return $this->storeManager->getDefaultStoreView()->getWebsiteId();
222  },
223  'status' => Status::STATUS_ENABLED,
224  ];
225  foreach ($defaultValues as $fixtureKey => $value) {
226  if (!isset($fixture[$fixtureKey])) {
227  $fixture[$fixtureKey] = $value;
228  }
229  }
230  }
231 
239  private function getFixtureValue($fixtureKey, $productId, $entityNumber, $fixtureMap)
240  {
241  $fixtureValue = isset($fixtureMap[$fixtureKey]) ? $fixtureMap[$fixtureKey] : null;
242  return $fixtureValue ? $this->getBindValue($fixtureValue, $productId, $entityNumber) : '';
243  }
244 
251  private function getBindValue($fixtureValue, $productId, $entityNumber)
252  {
253  return is_callable($fixtureValue)
254  ? call_user_func($fixtureValue, $productId, $entityNumber)
255  : $fixtureValue;
256  }
257 
266  private function urlRewriteHandler($productId, $entityNumber, $fixtureMap)
267  {
268  $binds = [];
269  $websiteIds = $fixtureMap['website_ids']($productId, $entityNumber);
271 
272  $bindPerStore = [];
273  $requestPath = $this->getFixtureValue('url_key', $productId, $entityNumber, $fixtureMap);
274  $targetPath = 'catalog/product/view/id/' . $productId;
275  $urlRewrite = $this->urlRewriteFactory
276  ->create()
277  ->setRequestPath($requestPath)
278  ->setTargetPath($targetPath)
279  ->setEntityId($productId)
280  ->setEntityType('product');
281  $binds[] = $urlRewrite->toArray();
282 
283  if (isset($fixtureMap['category_ids'])) {
284  $categoryId = $fixtureMap['category_ids']($productId, $entityNumber);
285  if (!isset($this->categories[$categoryId])) {
286  $this->categories[$categoryId] = $this->categoryCollectionFactory
287  ->create()
288  ->addIdFilter($categoryId)
289  ->addAttributeToSelect('url_path')
290  ->getFirstItem()
291  ->getUrlPath();
292  }
293  $urlRewrite->setMetadata(['category_id' => $categoryId])
294  ->setRequestPath($this->categories[$categoryId] . '/' . $requestPath)
295  ->setTargetPath($targetPath . '/category/' . $categoryId);
296  $binds[] = $urlRewrite->toArray();
297  }
298 
299  foreach ($websiteIds as $websiteId) {
300  if (!isset($this->storesPerWebsite[$websiteId])) {
301  $this->storesPerWebsite[$websiteId] = $this->storeCollectionFactory
302  ->create()
303  ->addWebsiteFilter($websiteId)
304  ->getAllIds();
305  }
306  foreach ($binds as $bind) {
307  foreach ($this->storesPerWebsite[$websiteId] as $storeId) {
308  $bindWithStore = $bind;
309  $bindWithStore['store_id'] = $storeId;
310  $bindWithStore['request_path'] .= $this->getUrlSuffix($storeId);
311  $bindPerStore[] = $bindWithStore;
312  }
313  }
314  }
315 
316  return $bindPerStore;
317  }
318 
325  private function getUrlSuffix($storeId)
326  {
327  if (!isset($this->productUrlSuffix[$storeId])) {
328  $this->productUrlSuffix[$storeId] = $this->scopeConfig->getValue(
331  $storeId
332  );
333  }
334  return $this->productUrlSuffix[$storeId];
335  }
336 }
$storeManager
$value
Definition: gender.phtml:16
__construct(\Magento\Catalog\Model\ProductFactory $productFactory, \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory, \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory, \Magento\Store\Model\ResourceModel\Store\CollectionFactory $storeCollectionFactory, EntityGeneratorFactory $entityGeneratorFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, ProductTemplateGeneratorFactory $productTemplateGeneratorFactory, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, $customTableMap=[])