PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/Magento/BundleImportExport/Model/Export/RowCustomizer.php

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