/vendor/magento/module-bundle-import-export/Model/Export/RowCustomizer.php

https://gitlab.com/yousafsyed/easternglamor · PHP · 325 lines · 171 code · 38 blank · 116 comment · 3 complexity · 7080861392e688fc3269c7feb823992a MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\BundleImportExport\Model\Export;
  7. use Magento\Catalog\Model\ResourceModel\Product\Collection;
  8. use Magento\CatalogImportExport\Model\Export\RowCustomizerInterface;
  9. use Magento\CatalogImportExport\Model\Import\Product as ImportProductModel;
  10. use Magento\Bundle\Model\ResourceModel\Selection\Collection as SelectionCollection;
  11. use Magento\ImportExport\Controller\Adminhtml\Import;
  12. use Magento\ImportExport\Model\Import as ImportModel;
  13. /**
  14. * Class RowCustomizer
  15. */
  16. class RowCustomizer implements RowCustomizerInterface
  17. {
  18. const BUNDLE_PRICE_TYPE_COL = 'bundle_price_type';
  19. const BUNDLE_SKU_TYPE_COL = 'bundle_sku_type';
  20. const BUNDLE_PRICE_VIEW_COL = 'bundle_price_view';
  21. const BUNDLE_WEIGHT_TYPE_COL = 'bundle_weight_type';
  22. const BUNDLE_VALUES_COL = 'bundle_values';
  23. const VALUE_FIXED = 'fixed';
  24. const VALUE_DYNAMIC = 'dynamic';
  25. const VALUE_PERCENT = 'percent';
  26. const VALUE_PRICE_RANGE = 'Price range';
  27. const VALUE_AS_LOW_AS = 'As low as';
  28. /**
  29. * Mapping for bundle types
  30. *
  31. * @var array
  32. */
  33. protected $typeMapping = [
  34. '0' => self::VALUE_DYNAMIC,
  35. '1' => self::VALUE_FIXED
  36. ];
  37. /**
  38. * Mapping for price views
  39. *
  40. * @var array
  41. */
  42. protected $priceViewMapping = [
  43. '0' => self::VALUE_PRICE_RANGE,
  44. '1' => self::VALUE_AS_LOW_AS
  45. ];
  46. /**
  47. * Mapping for price types
  48. *
  49. * @var array
  50. */
  51. protected $priceTypeMapping = [
  52. '0' => self::VALUE_FIXED,
  53. '1' => self::VALUE_PERCENT
  54. ];
  55. /**
  56. * Bundle product columns
  57. *
  58. * @var array
  59. */
  60. protected $bundleColumns = [
  61. self::BUNDLE_PRICE_TYPE_COL,
  62. self::BUNDLE_SKU_TYPE_COL,
  63. self::BUNDLE_PRICE_VIEW_COL,
  64. self::BUNDLE_WEIGHT_TYPE_COL,
  65. self::BUNDLE_VALUES_COL
  66. ];
  67. /**
  68. * Product's bundle data
  69. *
  70. * @var array
  71. */
  72. protected $bundleData = [];
  73. /**
  74. * Prepare data for export
  75. *
  76. * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
  77. * @param int[] $productIds
  78. * @return $this
  79. */
  80. public function prepareData($collection, $productIds)
  81. {
  82. $productCollection = clone $collection;
  83. $productCollection->addAttributeToFilter(
  84. 'entity_id',
  85. ['in' => $productIds]
  86. )->addAttributeToFilter(
  87. 'type_id',
  88. ['eq' => \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE]
  89. );
  90. return $this->populateBundleData($productCollection);
  91. }
  92. /**
  93. * Set headers columns
  94. *
  95. * @param array $columns
  96. * @return array
  97. */
  98. public function addHeaderColumns($columns)
  99. {
  100. $columns = array_merge($columns, $this->bundleColumns);
  101. return $columns;
  102. }
  103. /**
  104. * Add data for export
  105. *
  106. * @param array $dataRow
  107. * @param int $productId
  108. * @return array
  109. */
  110. public function addData($dataRow, $productId)
  111. {
  112. if (!empty($this->bundleData[$productId])) {
  113. $dataRow = array_merge($this->cleanNotBundleAdditionalAttributes($dataRow), $this->bundleData[$productId]);
  114. }
  115. return $dataRow;
  116. }
  117. /**
  118. * Calculate the largest links block
  119. *
  120. * @param array $additionalRowsCount
  121. * @param int $productId
  122. * @return array
  123. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  124. */
  125. public function getAdditionalRowsCount($additionalRowsCount, $productId)
  126. {
  127. return $additionalRowsCount;
  128. }
  129. /**
  130. * Populate bundle product data
  131. *
  132. * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
  133. * @return $this
  134. */
  135. protected function populateBundleData($collection)
  136. {
  137. foreach ($collection as $product) {
  138. $id = $product->getId();
  139. $this->bundleData[$id][self::BUNDLE_PRICE_TYPE_COL] = $this->getTypeValue($product->getPriceType());
  140. $this->bundleData[$id][self::BUNDLE_SKU_TYPE_COL] = $this->getTypeValue($product->getSkuType());
  141. $this->bundleData[$id][self::BUNDLE_PRICE_VIEW_COL] = $this->getPriceViewValue($product->getPriceView());
  142. $this->bundleData[$id][self::BUNDLE_WEIGHT_TYPE_COL] = $this->getTypeValue($product->getWeightType());
  143. $this->bundleData[$id][self::BUNDLE_VALUES_COL] = $this->getFormattedBundleOptionValues($product);
  144. }
  145. return $this;
  146. }
  147. /**
  148. * Retrieve formatted bundle options
  149. *
  150. * @param \Magento\Catalog\Model\Product $product
  151. * @return string
  152. */
  153. protected function getFormattedBundleOptionValues($product)
  154. {
  155. /** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionsCollection */
  156. $optionsCollection = $product->getTypeInstance()
  157. ->getOptionsCollection($product)
  158. ->setOrder('position', Collection::SORT_ORDER_ASC);
  159. $bundleData = '';
  160. foreach ($optionsCollection as $option) {
  161. $bundleData .= $this->getFormattedBundleSelections(
  162. $this->getFormattedOptionValues($option),
  163. $product->getTypeInstance()
  164. ->getSelectionsCollection([$option->getId()], $product)
  165. ->setOrder('position', Collection::SORT_ORDER_ASC)
  166. );
  167. }
  168. return rtrim($bundleData, ImportProductModel::PSEUDO_MULTI_LINE_SEPARATOR);
  169. }
  170. /**
  171. * Retrieve formatted bundle selections
  172. *
  173. * @param string $optionValues
  174. * @param SelectionCollection $selections
  175. * @return string
  176. */
  177. protected function getFormattedBundleSelections($optionValues, SelectionCollection $selections)
  178. {
  179. $bundleData = '';
  180. $selections->addAttributeToSort('position');
  181. foreach ($selections as $selection) {
  182. $selectionData = [
  183. 'sku' => $selection->getSku(),
  184. 'price' => $selection->getSelectionPriceValue(),
  185. 'default' => $selection->getIsDefault(),
  186. 'default_qty' => $selection->getSelectionQty(),
  187. 'price_type' => $this->getPriceTypeValue($selection->getSelectionPriceType())
  188. ];
  189. $bundleData .= $optionValues
  190. . ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR
  191. . implode(
  192. ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
  193. array_map(
  194. function ($value, $key) {
  195. return $key . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR . $value;
  196. },
  197. $selectionData,
  198. array_keys($selectionData)
  199. )
  200. )
  201. . ImportProductModel::PSEUDO_MULTI_LINE_SEPARATOR;
  202. }
  203. return $bundleData;
  204. }
  205. /**
  206. * Retrieve option value of bundle product
  207. *
  208. * @param \Magento\Bundle\Model\Option $option
  209. * @return string
  210. */
  211. protected function getFormattedOptionValues($option)
  212. {
  213. return 'name' . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR
  214. . $option->getTitle() . ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR
  215. . 'type' . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR
  216. . $option->getType() . ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR
  217. . 'required' . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR
  218. . $option->getRequired();
  219. }
  220. /**
  221. * Retrieve bundle type value by code
  222. *
  223. * @param string $type
  224. * @return string
  225. */
  226. protected function getTypeValue($type)
  227. {
  228. return isset($this->typeMapping[$type]) ? $this->typeMapping[$type] : self::VALUE_DYNAMIC;
  229. }
  230. /**
  231. * Retrieve bundle price view value by code
  232. *
  233. * @param string $type
  234. * @return string
  235. */
  236. protected function getPriceViewValue($type)
  237. {
  238. return isset($this->priceViewMapping[$type]) ? $this->priceViewMapping[$type] : self::VALUE_PRICE_RANGE;
  239. }
  240. /**
  241. * Retrieve bundle price type value by code
  242. *
  243. * @param string $type
  244. * @return string
  245. */
  246. protected function getPriceTypeValue($type)
  247. {
  248. return isset($this->priceTypeMapping[$type]) ? $this->priceTypeMapping[$type] : null;
  249. }
  250. /**
  251. * Remove bundle specified additional attributes as now they are stored in specified columns
  252. *
  253. * @param array $dataRow
  254. * @return array
  255. */
  256. protected function cleanNotBundleAdditionalAttributes($dataRow)
  257. {
  258. if (!empty($dataRow['additional_attributes'])) {
  259. $additionalAttributes = explode(
  260. ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
  261. $dataRow['additional_attributes']
  262. );
  263. $dataRow['additional_attributes'] = $this->getNotBundleAttributes($additionalAttributes);
  264. }
  265. return $dataRow;
  266. }
  267. /**
  268. * Retrieve not bundle additional attributes
  269. *
  270. * @param array $additionalAttributes
  271. * @return string
  272. */
  273. protected function getNotBundleAttributes($additionalAttributes)
  274. {
  275. $cleanedAdditionalAttributes = '';
  276. foreach ($additionalAttributes as $attribute) {
  277. list($attributeCode, $attributeValue) = explode(ImportProductModel::PAIR_NAME_VALUE_SEPARATOR, $attribute);
  278. if (!in_array('bundle_' . $attributeCode, $this->bundleColumns)) {
  279. $cleanedAdditionalAttributes .= $attributeCode
  280. . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR
  281. . $attributeValue
  282. . ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
  283. }
  284. }
  285. return rtrim($cleanedAdditionalAttributes, ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR);
  286. }
  287. }