Contact.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace Dotdigitalgroup\Email\Model\Apiconnector;
  3. /**
  4. * manages the sync of dotmailer Contact.
  5. */
  6. class Contact
  7. {
  8. /**
  9. * @var \Dotdigitalgroup\Email\Model\ResourceModel\Contact
  10. */
  11. private $contactResource;
  12. /**
  13. * @var mixed
  14. */
  15. private $start;
  16. /**
  17. * @var int
  18. */
  19. private $countCustomers = 0;
  20. /**
  21. * @var \Dotdigitalgroup\Email\Helper\Data
  22. */
  23. private $helper;
  24. /**
  25. * @var \Dotdigitalgroup\Email\Model\Apiconnector\Customer
  26. */
  27. private $emailCustomer;
  28. /**
  29. * @var \Dotdigitalgroup\Email\Helper\File
  30. */
  31. private $file;
  32. /**
  33. * @var \Dotdigitalgroup\Email\Model\Apiconnector\ContactImportQueueExport
  34. */
  35. public $contactImportQueueExport;
  36. /**
  37. * @var \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory
  38. */
  39. private $contactCollectionFactory;
  40. /**
  41. * Contact constructor.
  42. *
  43. * @param CustomerFactory $customerFactory
  44. * @param \Dotdigitalgroup\Email\Helper\File $file
  45. * @param \Dotdigitalgroup\Email\Helper\Data $helper
  46. * @param \Dotdigitalgroup\Email\Model\ResourceModel\Contact $contactResource
  47. * @param ContactImportQueueExport $contactImportQueueExport
  48. * @param \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory $contactCollectionFactory
  49. */
  50. public function __construct(
  51. \Dotdigitalgroup\Email\Model\Apiconnector\CustomerFactory $customerFactory,
  52. \Dotdigitalgroup\Email\Helper\File $file,
  53. \Dotdigitalgroup\Email\Helper\Data $helper,
  54. \Dotdigitalgroup\Email\Model\ResourceModel\Contact $contactResource,
  55. \Dotdigitalgroup\Email\Model\Apiconnector\ContactImportQueueExport $contactImportQueueExport,
  56. \Dotdigitalgroup\Email\Model\ResourceModel\Contact\CollectionFactory $contactCollectionFactory
  57. ) {
  58. $this->file = $file;
  59. $this->helper = $helper;
  60. //email contact
  61. $this->emailCustomer = $customerFactory;
  62. $this->contactResource = $contactResource;
  63. $this->contactImportQueueExport = $contactImportQueueExport;
  64. $this->contactCollectionFactory = $contactCollectionFactory;
  65. }
  66. /**
  67. * Contact sync.
  68. *
  69. * @return array
  70. */
  71. public function sync()
  72. {
  73. //result message
  74. $result = ['success' => true, 'message' => ''];
  75. //starting time for sync
  76. $this->start = microtime(true);
  77. //export bulk contacts
  78. foreach ($this->helper->getWebsites() as $website) {
  79. $apiEnabled = $this->helper->isEnabled($website);
  80. $customerSyncEnabled = $this->helper->isCustomerSyncEnabled(
  81. $website
  82. );
  83. $customerAddressBook = $this->helper->getCustomerAddressBook(
  84. $website
  85. );
  86. //api, customer sync and customer address book must be enabled
  87. if ($apiEnabled && $customerSyncEnabled && $customerAddressBook) {
  88. //start log
  89. $contactsUpdated = $this->exportCustomersForWebsite($website);
  90. // show message for any number of customers
  91. if ($contactsUpdated) {
  92. $result['message'] .= $website->getName()
  93. . ', updated contacts ' . $contactsUpdated;
  94. }
  95. }
  96. }
  97. //sync proccessed
  98. if ($this->countCustomers) {
  99. $message = '----------- Customer sync ----------- : ' .
  100. gmdate('H:i:s', microtime(true) - $this->start) .
  101. ', Total contacts = ' . $this->countCustomers;
  102. $this->helper->log($message);
  103. $message .= $result['message'];
  104. $result['message'] = $message;
  105. }
  106. return $result;
  107. }
  108. /**
  109. * @param \Magento\Store\Api\Data\WebsiteInterface $website
  110. *
  111. * @return int
  112. */
  113. public function exportCustomersForWebsite(\Magento\Store\Api\Data\WebsiteInterface $website)
  114. {
  115. $allMappedHash = [];
  116. //admin sync limit of batch size for contacts
  117. $syncLimit = $this->helper->getSyncLimit($website);
  118. //address book id mapped
  119. $customerAddressBook = $this->helper->getCustomerAddressBook($website);
  120. //skip website if address book not mapped
  121. if (!$customerAddressBook) {
  122. return 0;
  123. }
  124. $onlySubscribers = $this->helper->isOnlySubscribersForContactSync($website->getId());
  125. $contacts = $this->contactCollectionFactory->create();
  126. $contacts = ($onlySubscribers) ? $contacts->getContactsToImportByWebsite($website->getId(), $syncLimit, true) :
  127. $contacts->getContactsToImportByWebsite($website->getId(), $syncLimit);
  128. // no contacts found
  129. if (!$contacts->getSize()) {
  130. return 0;
  131. }
  132. //customer filename
  133. $customersFile = strtolower(
  134. $website->getCode() . '_customers_' . date('d_m_Y_His') . '.csv'
  135. );
  136. $this->helper->log('Customers file : ' . $customersFile);
  137. //get customers ids
  138. $customerIds = $contacts->getColumnValues('customer_id');
  139. /*
  140. * HEADERS.
  141. */
  142. $mappedHash = $this->helper->getWebsiteCustomerMappingDatafields(
  143. $website
  144. );
  145. $headers = $mappedHash;
  146. //custom customer attributes
  147. $customAttributes = $this->helper->getCustomAttributes($website);
  148. if ($customAttributes) {
  149. foreach ($customAttributes as $data) {
  150. $headers[] = $data['datafield'];
  151. $allMappedHash[$data['attribute']] = $data['datafield'];
  152. }
  153. }
  154. $headers[] = 'Email';
  155. $headers[] = 'EmailType';
  156. $this->file->outputCSV(
  157. $this->file->getFilePath($customersFile),
  158. $headers
  159. );
  160. /*
  161. * END HEADERS.
  162. */
  163. //customer collection
  164. $customerCollection = $this->contactResource->buildCustomerCollection($customerIds);
  165. //Customer sales data
  166. $salesData = $this->getCustomerSalesData($customerIds, $website->getId());
  167. $this->createCsvFile(
  168. $customerCollection,
  169. $mappedHash,
  170. $customAttributes,
  171. $customersFile,
  172. $salesData
  173. );
  174. $customerNum = count($customerIds);
  175. $this->helper->log(
  176. 'Website : ' . $website->getName() . ', customers = ' . $customerNum .
  177. ', execution time :' . gmdate('H:i:s', microtime(true) - $this->start)
  178. );
  179. //file was created - continue to queue the export
  180. $this->contactImportQueueExport->enqueueForExport(
  181. $website,
  182. $customersFile,
  183. $customerNum,
  184. $customerIds,
  185. $this->contactResource
  186. );
  187. $this->countCustomers += $customerNum;
  188. return $customerNum;
  189. }
  190. /**
  191. * @param \Magento\Customer\Model\ResourceModel\Customer\Collection $customerCollection
  192. * @param array $mappedHash
  193. * @param array $customAttributes
  194. * @param string $customersFile
  195. * @param array $salesData
  196. */
  197. private function createCsvFile(
  198. $customerCollection,
  199. $mappedHash,
  200. $customAttributes,
  201. $customersFile,
  202. $salesData
  203. ) {
  204. foreach ($customerCollection as $customer) {
  205. if (isset($salesData[$customer->getId()])) {
  206. $customer = $this->setSalesDataOnCustomer($salesData[$customer->getId()], $customer);
  207. }
  208. $connectorCustomer = $this->emailCustomer->create();
  209. $connectorCustomer->setMappingHash($mappedHash);
  210. $connectorCustomer->setContactData($customer);
  211. if ($connectorCustomer) {
  212. foreach ($customAttributes as $data) {
  213. $attribute = $data['attribute'];
  214. $value = $customer->getData($attribute);
  215. $connectorCustomer->setData($value);
  216. }
  217. }
  218. //contact email and email type
  219. $connectorCustomer->setData($customer->getEmail());
  220. $connectorCustomer->setData('Html');
  221. // save csv file data for customers
  222. $this->file->outputCSV(
  223. $this->file->getFilePath($customersFile),
  224. $connectorCustomer->toCSVArray()
  225. );
  226. //clear collection and free memory
  227. $customer->clearInstance();
  228. }
  229. }
  230. /**
  231. * @param array $salesData
  232. * @param \Magento\Customer\Model\Customer $customer
  233. *
  234. * @return \Magento\Customer\Model\Customer
  235. */
  236. private function setSalesDataOnCustomer($salesData, $customer)
  237. {
  238. foreach ($salesData as $column => $value) {
  239. $customer->setData($column, $value);
  240. }
  241. return $customer;
  242. }
  243. /**
  244. * @param array $customerIds
  245. * @param int $websiteId
  246. *
  247. * @return array
  248. */
  249. private function getCustomerSalesData($customerIds, $websiteId = 0)
  250. {
  251. $statuses = $this->helper->getWebsiteConfig(
  252. \Dotdigitalgroup\Email\Helper\Config::XML_PATH_CONNECTOR_SYNC_DATA_FIELDS_STATUS,
  253. $websiteId
  254. );
  255. $statuses = explode(',', $statuses);
  256. return $this->contactResource
  257. ->getSalesDataForCustomersWithOrderStatusesAndBrand($customerIds, $statuses);
  258. }
  259. }