Product.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. namespace Dotdigitalgroup\Email\Model\Connector;
  3. /**
  4. * Transactional data for catalog products to sync.
  5. *
  6. * @SuppressWarnings(PHPMD.TooManyFields)
  7. */
  8. class Product
  9. {
  10. /**
  11. * @var string
  12. */
  13. public $id;
  14. /**
  15. * @var string
  16. */
  17. public $name = '';
  18. /**
  19. * @var string
  20. */
  21. public $sku = '';
  22. /**
  23. * @var string
  24. */
  25. public $status = '';
  26. /**
  27. * @var string
  28. */
  29. public $visibility = '';
  30. /**
  31. * @var float
  32. */
  33. public $price = 0;
  34. /**
  35. * @var float
  36. */
  37. public $specialPrice = 0;
  38. /**
  39. * @var array
  40. */
  41. public $categories = [];
  42. /**
  43. * @var string
  44. */
  45. public $url = '';
  46. /**
  47. * @var string
  48. */
  49. public $imagePath = '';
  50. /**
  51. * @var string
  52. */
  53. public $shortDescription = '';
  54. /**
  55. * @var float
  56. */
  57. public $stock = 0;
  58. /**
  59. * @var array
  60. */
  61. public $websites = [];
  62. /**
  63. * @var \Dotdigitalgroup\Email\Helper\Data
  64. */
  65. public $helper;
  66. /**
  67. * @var \Magento\Store\Model\StoreManagerInterface
  68. */
  69. public $storeManager;
  70. /**
  71. * @var \Magento\Catalog\Model\Product\Attribute\Source\StatusFactory
  72. */
  73. public $statusFactory;
  74. /**
  75. * @var \Magento\Catalog\Model\Product\VisibilityFactory
  76. */
  77. public $visibilityFactory;
  78. /**
  79. * @var \Magento\Catalog\Model\Product\Media\ConfigFactory
  80. */
  81. public $mediaConfigFactory;
  82. /**
  83. * @var \Magento\CatalogInventory\Model\Stock\ItemFactory
  84. */
  85. public $itemFactory;
  86. /**
  87. * @var \Magento\Framework\Stdlib\StringUtils
  88. */
  89. private $stringUtils;
  90. /**
  91. * Product constructor.
  92. *
  93. * @param \Magento\Store\Model\StoreManagerInterface $storeManagerInterface
  94. * @param \Dotdigitalgroup\Email\Helper\Data $helper
  95. * @param \Magento\CatalogInventory\Model\Stock\ItemFactory $itemFactory
  96. * @param \Magento\Catalog\Model\Product\Media\ConfigFactory $mediaConfigFactory
  97. * @param \Magento\Catalog\Model\Product\Attribute\Source\StatusFactory $statusFactory
  98. * @param \Magento\Catalog\Model\Product\VisibilityFactory $visibilityFactory
  99. * @param \Magento\Framework\Stdlib\StringUtils $stringUtils
  100. */
  101. public function __construct(
  102. \Magento\Store\Model\StoreManagerInterface $storeManagerInterface,
  103. \Dotdigitalgroup\Email\Helper\Data $helper,
  104. \Magento\CatalogInventory\Model\Stock\ItemFactory $itemFactory,
  105. \Magento\Catalog\Model\Product\Media\ConfigFactory $mediaConfigFactory,
  106. \Magento\Catalog\Model\Product\Attribute\Source\StatusFactory $statusFactory,
  107. \Magento\Catalog\Model\Product\VisibilityFactory $visibilityFactory,
  108. \Magento\Framework\Stdlib\StringUtils $stringUtils
  109. ) {
  110. $this->itemFactory = $itemFactory;
  111. $this->mediaConfigFactory = $mediaConfigFactory;
  112. $this->visibilityFactory = $visibilityFactory;
  113. $this->statusFactory = $statusFactory;
  114. $this->helper = $helper;
  115. $this->storeManager = $storeManagerInterface;
  116. $this->stringUtils = $stringUtils;
  117. }
  118. /**
  119. * Set the product data.
  120. *
  121. * @param \Magento\Catalog\Model\Product $product
  122. *
  123. * @return $this
  124. */
  125. public function setProduct($product)
  126. {
  127. $this->id = $product->getId();
  128. $this->sku = $product->getSku();
  129. $this->name = $product->getName();
  130. $status = $this->statusFactory->create()
  131. ->getOptionText($product->getStatus());
  132. $this->status = $status->getText();
  133. $options = $this->visibilityFactory->create()
  134. ->getOptionArray();
  135. $this->visibility = (string)$options[$product->getVisibility()];
  136. $this->price = (float)number_format(
  137. $product->getPrice(),
  138. 2,
  139. '.',
  140. ''
  141. );
  142. $this->specialPrice = (float)number_format(
  143. $product->getSpecialPrice(),
  144. 2,
  145. '.',
  146. ''
  147. );
  148. $this->url = $product->getProductUrl();
  149. $this->imagePath = $this->mediaConfigFactory->create()
  150. ->getMediaUrl($product->getSmallImage());
  151. $stock = $this->itemFactory->create()
  152. ->setProduct($product);
  153. $this->stock = (float)number_format($stock->getQty(), 2, '.', '');
  154. $shortDescription = $product->getShortDescription();
  155. //limit short description
  156. if ($this->stringUtils->strlen($shortDescription) > \Dotdigitalgroup\Email\Helper\Data::DM_FIELD_LIMIT) {
  157. $shortDescription = mb_substr($shortDescription, 0, \Dotdigitalgroup\Email\Helper\Data::DM_FIELD_LIMIT);
  158. }
  159. $this->shortDescription = $shortDescription;
  160. //category data
  161. $count = 0;
  162. $categoryCollection = $product->getCategoryCollection()
  163. ->addNameToResult();
  164. foreach ($categoryCollection as $cat) {
  165. $this->categories[$count]['Id'] = $cat->getId();
  166. $this->categories[$count]['Name'] = $cat->getName();
  167. ++$count;
  168. }
  169. //website data
  170. $count = 0;
  171. $websiteIds = $product->getWebsiteIds();
  172. foreach ($websiteIds as $websiteId) {
  173. $website = $this->storeManager->getWebsite(
  174. $websiteId
  175. );
  176. $this->websites[$count]['Id'] = $website->getId();
  177. $this->websites[$count]['Name'] = $website->getName();
  178. ++$count;
  179. }
  180. $this->processProductOptions($product);
  181. unset(
  182. $this->itemFactory,
  183. $this->mediaConfigFactory,
  184. $this->visibilityFactory,
  185. $this->statusFactory,
  186. $this->helper,
  187. $this->storeManager
  188. );
  189. return $this;
  190. }
  191. /**
  192. * @param mixed $product
  193. *
  194. * @return null
  195. */
  196. private function processProductOptions($product)
  197. {
  198. //bundle product options
  199. if ($product->getTypeId()
  200. == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE
  201. ) {
  202. $optionCollection = $product->getTypeInstance()
  203. ->getOptionsCollection($product);
  204. $selectionCollection = $product->getTypeInstance()
  205. ->getSelectionsCollection(
  206. $product->getTypeInstance()->getOptionsIds($product),
  207. $product
  208. );
  209. $options = $optionCollection->appendSelections(
  210. $selectionCollection
  211. );
  212. foreach ($options as $option) {
  213. $trimmedTitle = str_replace(' ', '', $option->getDefaultTitle());
  214. if (!$this->textIsValidForInsightDataKey($trimmedTitle)) {
  215. continue;
  216. }
  217. $count = 0;
  218. $selections = $option->getSelections();
  219. $sOptions = [];
  220. foreach ($selections as $selection) {
  221. $sOptions[$count]['name'] = $selection->getName();
  222. $sOptions[$count]['sku'] = $selection->getSku();
  223. $sOptions[$count]['id'] = $selection->getProductId();
  224. $sOptions[$count]['price'] = (float)number_format(
  225. $selection->getPrice(),
  226. 2,
  227. '.',
  228. ''
  229. );
  230. ++$count;
  231. }
  232. $this->$trimmedTitle = $sOptions;
  233. }
  234. }
  235. //configurable product options
  236. if ($product->getTypeId() == 'configurable') {
  237. $productAttributeOptions = $product->getTypeInstance()
  238. ->getConfigurableAttributesAsArray($product);
  239. foreach ($productAttributeOptions as $productAttribute) {
  240. $trimmedLabel = str_replace(' ', '', $productAttribute['label']);
  241. if (!$this->textIsValidForInsightDataKey($trimmedLabel)) {
  242. continue;
  243. }
  244. $count = 0;
  245. $options = [];
  246. foreach ($productAttribute['values'] as $attribute) {
  247. $options[$count]['option'] = $attribute['default_label'];
  248. if (isset($attribute['pricing_value'])) {
  249. $options[$count]['price'] = (float)number_format(
  250. $attribute['pricing_value'],
  251. 2,
  252. '.',
  253. ''
  254. );
  255. }
  256. ++$count;
  257. }
  258. $this->$trimmedLabel = $options;
  259. }
  260. }
  261. }
  262. /**
  263. * Exposes the class as an array of objects.
  264. *
  265. * @return array
  266. */
  267. public function expose()
  268. {
  269. return array_diff_key(
  270. get_object_vars($this),
  271. array_flip([
  272. 'storeManager',
  273. 'helper',
  274. 'itemFactory',
  275. 'mediaConfigFactory',
  276. 'visibilityFactory',
  277. 'statusFactory',
  278. 'storeManager'
  279. ])
  280. );
  281. }
  282. /**
  283. * @param string $label
  284. *
  285. * https://support.dotmailer.com/hc/en-gb/articles/212214538-Using-Insight-data-developers-guide-#restrictkeys
  286. *
  287. * @return false|int
  288. */
  289. private function textIsValidForInsightDataKey($label)
  290. {
  291. return preg_match('/^[a-zA-Z_\\\\-][a-zA-Z0-9_\\\\-]*$/', $label);
  292. }
  293. }