AbstractCustomer.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CustomerImportExport\Model\Import;
  7. use Magento\ImportExport\Model\Import;
  8. use Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\Storage;
  9. use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
  10. /**
  11. * Import entity abstract customer model
  12. *
  13. * @api
  14. *
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. * @since 100.0.2
  17. */
  18. abstract class AbstractCustomer extends \Magento\ImportExport\Model\Import\Entity\AbstractEav
  19. {
  20. /**#@+
  21. * Permanent column names
  22. *
  23. * Names that begins with underscore is not an attribute. This name convention is for
  24. * to avoid interference with same attribute name.
  25. */
  26. const COLUMN_WEBSITE = '_website';
  27. const COLUMN_EMAIL = '_email';
  28. const COLUMN_DEFAULT_BILLING = 'default_billing';
  29. const COLUMN_DEFAULT_SHIPPING = 'default_shipping';
  30. /**#@-*/
  31. /**#@+
  32. * Error codes
  33. */
  34. const ERROR_WEBSITE_IS_EMPTY = 'websiteIsEmpty';
  35. const ERROR_EMAIL_IS_EMPTY = 'emailIsEmpty';
  36. const ERROR_INVALID_WEBSITE = 'invalidWebsite';
  37. const ERROR_INVALID_EMAIL = 'invalidEmail';
  38. const ERROR_VALUE_IS_REQUIRED = 'valueIsRequired';
  39. const ERROR_CUSTOMER_NOT_FOUND = 'customerNotFound';
  40. /**#@-*/
  41. /**#@-*/
  42. protected $_ignoredAttributes = ['website_id', 'store_id',
  43. self::COLUMN_DEFAULT_BILLING, self::COLUMN_DEFAULT_SHIPPING];
  44. /**
  45. * Customer collection wrapper
  46. *
  47. * @var Storage
  48. */
  49. protected $_customerStorage;
  50. /**
  51. * @var \Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\StorageFactory
  52. */
  53. protected $_storageFactory;
  54. /**
  55. * If we should check column names
  56. *
  57. * @var bool
  58. */
  59. protected $needColumnCheck = true;
  60. /**
  61. * {@inheritdoc}
  62. */
  63. protected $masterAttributeCode = '_email';
  64. /**
  65. * @param \Magento\Framework\Stdlib\StringUtils $string
  66. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  67. * @param \Magento\ImportExport\Model\ImportFactory $importFactory
  68. * @param \Magento\ImportExport\Model\ResourceModel\Helper $resourceHelper
  69. * @param \Magento\Framework\App\ResourceConnection $resource
  70. * @param ProcessingErrorAggregatorInterface $errorAggregator
  71. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  72. * @param \Magento\ImportExport\Model\Export\Factory $collectionFactory
  73. * @param \Magento\Eav\Model\Config $eavConfig
  74. * @param \Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\StorageFactory $storageFactory
  75. * @param array $data
  76. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  77. */
  78. public function __construct(
  79. \Magento\Framework\Stdlib\StringUtils $string,
  80. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  81. \Magento\ImportExport\Model\ImportFactory $importFactory,
  82. \Magento\ImportExport\Model\ResourceModel\Helper $resourceHelper,
  83. \Magento\Framework\App\ResourceConnection $resource,
  84. ProcessingErrorAggregatorInterface $errorAggregator,
  85. \Magento\Store\Model\StoreManagerInterface $storeManager,
  86. \Magento\ImportExport\Model\Export\Factory $collectionFactory,
  87. \Magento\Eav\Model\Config $eavConfig,
  88. \Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\StorageFactory $storageFactory,
  89. array $data = []
  90. ) {
  91. $this->_storageFactory = $storageFactory;
  92. parent::__construct(
  93. $string,
  94. $scopeConfig,
  95. $importFactory,
  96. $resourceHelper,
  97. $resource,
  98. $errorAggregator,
  99. $storeManager,
  100. $collectionFactory,
  101. $eavConfig,
  102. $data
  103. );
  104. $this->addMessageTemplate(self::ERROR_WEBSITE_IS_EMPTY, __('Please specify a website.'));
  105. $this->addMessageTemplate(
  106. self::ERROR_EMAIL_IS_EMPTY,
  107. __("An email wasn't specified. Enter the email and try again.")
  108. );
  109. $this->addMessageTemplate(self::ERROR_INVALID_WEBSITE, __('We found an invalid value in a website column.'));
  110. $this->addMessageTemplate(self::ERROR_INVALID_EMAIL, __('Please enter a valid email.'));
  111. $this->addMessageTemplate(self::ERROR_VALUE_IS_REQUIRED, __('Please make sure attribute "%s" is not empty.'));
  112. $this->addMessageTemplate(
  113. self::ERROR_CUSTOMER_NOT_FOUND,
  114. __('We can\'t find a customer who matches this email and website code.')
  115. );
  116. $this->_initCustomers($data)->_initWebsites(true);
  117. }
  118. /**
  119. * Initialize existent customers data
  120. *
  121. * @param array $data
  122. * @return $this
  123. */
  124. protected function _initCustomers(array $data)
  125. {
  126. if (!isset($data['page_size'])) {
  127. $data['page_size'] = $this->_pageSize;
  128. }
  129. $this->_customerStorage = isset(
  130. $data['customer_storage']
  131. ) ? $data['customer_storage'] : $this->_storageFactory->create(
  132. ['data' => $data]
  133. );
  134. return $this;
  135. }
  136. /**
  137. * Get customer id if customer is present in database
  138. *
  139. * @param string $email
  140. * @param string $websiteCode
  141. * @return bool|int
  142. */
  143. protected function _getCustomerId($email, $websiteCode)
  144. {
  145. $email = strtolower(trim($email));
  146. if (isset($this->_websiteCodeToId[$websiteCode])) {
  147. $websiteId = $this->_websiteCodeToId[$websiteCode];
  148. return $this->_customerStorage->getCustomerId($email, $websiteId);
  149. }
  150. return false;
  151. }
  152. /**
  153. * Validate data row
  154. *
  155. * @param array $rowData
  156. * @param int $rowNumber
  157. * @return bool
  158. */
  159. public function validateRow(array $rowData, $rowNumber)
  160. {
  161. if (isset($this->_validatedRows[$rowNumber])) {
  162. // check that row is already validated
  163. return !$this->getErrorAggregator()->isRowInvalid($rowNumber);
  164. }
  165. $this->_validatedRows[$rowNumber] = true;
  166. $this->_processedEntitiesCount++;
  167. if ($this->getBehavior($rowData) == \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE) {
  168. $this->_validateRowForUpdate($rowData, $rowNumber);
  169. } elseif ($this->getBehavior($rowData) == \Magento\ImportExport\Model\Import::BEHAVIOR_DELETE) {
  170. $this->_validateRowForDelete($rowData, $rowNumber);
  171. }
  172. return !$this->getErrorAggregator()->isRowInvalid($rowNumber);
  173. }
  174. /**
  175. * Validate data row for add/update behaviour
  176. *
  177. * @param array $rowData
  178. * @param int $rowNumber
  179. * @return null
  180. */
  181. abstract protected function _validateRowForUpdate(array $rowData, $rowNumber);
  182. /**
  183. * Validate data row for delete behaviour
  184. *
  185. * @param array $rowData
  186. * @param int $rowNumber
  187. * @return null
  188. */
  189. abstract protected function _validateRowForDelete(array $rowData, $rowNumber);
  190. /**
  191. * General check of unique key
  192. *
  193. * @param array $rowData
  194. * @param int $rowNumber
  195. * @return bool
  196. */
  197. protected function _checkUniqueKey(array $rowData, $rowNumber)
  198. {
  199. if (empty($rowData[static::COLUMN_WEBSITE])) {
  200. $this->addRowError(static::ERROR_WEBSITE_IS_EMPTY, $rowNumber, static::COLUMN_WEBSITE);
  201. } elseif (empty($rowData[static::COLUMN_EMAIL])) {
  202. $this->addRowError(static::ERROR_EMAIL_IS_EMPTY, $rowNumber, static::COLUMN_EMAIL);
  203. } else {
  204. $email = strtolower($rowData[static::COLUMN_EMAIL]);
  205. $website = $rowData[static::COLUMN_WEBSITE];
  206. if (!\Zend_Validate::is($email, \Magento\Framework\Validator\EmailAddress::class)) {
  207. $this->addRowError(static::ERROR_INVALID_EMAIL, $rowNumber, static::COLUMN_EMAIL);
  208. } elseif (!isset($this->_websiteCodeToId[$website])) {
  209. $this->addRowError(static::ERROR_INVALID_WEBSITE, $rowNumber, static::COLUMN_WEBSITE);
  210. }
  211. }
  212. return !$this->getErrorAggregator()->isRowInvalid($rowNumber);
  213. }
  214. /**
  215. * Get customer storage
  216. *
  217. * @return Storage
  218. */
  219. public function getCustomerStorage()
  220. {
  221. return $this->_customerStorage;
  222. }
  223. /**
  224. * Returns id of option by value for select and multiselect attributes
  225. *
  226. * @param array $attributeParameters Parameters of an attribute
  227. * @param int|string $value A value of an attribute
  228. * @return int An option id of attribute
  229. * @since 100.2.0
  230. */
  231. protected function getSelectAttrIdByValue(array $attributeParameters, $value)
  232. {
  233. return isset($attributeParameters['options'][strtolower($value)])
  234. ? $attributeParameters['options'][strtolower($value)]
  235. : 0;
  236. }
  237. /**
  238. * Returns multiple value separator
  239. *
  240. * @return string
  241. * @since 100.2.0
  242. */
  243. protected function getMultipleValueSeparator()
  244. {
  245. return isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR])
  246. ? $this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]
  247. : Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
  248. }
  249. }