ReadSnapshotPlugin.php 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Plugin\Model\ResourceModel;
  7. use Magento\Catalog\Api\Data\CategoryInterface;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Eav\Model\Config as EavConfig;
  10. use Magento\Eav\Model\ResourceModel\ReadSnapshot;
  11. use Magento\Framework\EntityManager\MetadataPool;
  12. /**
  13. * Extend Eav ReadSnapshot by adding data from product or category attributes with global scope.
  14. * Default ReadSnapshot returns only data for current scope where entity is editing, but attributes with global scope,
  15. * e.g. price, is written only to default scope (store_id = 0) in case Catalog Price Scope set to "Global"
  16. */
  17. class ReadSnapshotPlugin
  18. {
  19. /**
  20. * @var MetadataPool
  21. */
  22. private $metadataPool;
  23. /**
  24. * @var EavConfig
  25. */
  26. private $config;
  27. /**
  28. * @param MetadataPool $metadataPool
  29. * @param EavConfig $config
  30. */
  31. public function __construct(
  32. MetadataPool $metadataPool,
  33. EavConfig $config
  34. ) {
  35. $this->metadataPool = $metadataPool;
  36. $this->config = $config;
  37. }
  38. /**
  39. * @param ReadSnapshot $subject
  40. * @param array $entityData
  41. * @param string $entityType
  42. * @return array
  43. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  44. */
  45. public function afterExecute(ReadSnapshot $subject, array $entityData, $entityType)
  46. {
  47. if (!in_array($entityType, [ProductInterface::class, CategoryInterface::class], true)) {
  48. return $entityData;
  49. }
  50. $metadata = $this->metadataPool->getMetadata($entityType);
  51. $connection = $metadata->getEntityConnection();
  52. $globalAttributes = [];
  53. $attributesMap = [];
  54. $eavEntityType = $metadata->getEavEntityType();
  55. $attributes = null === $eavEntityType
  56. ? []
  57. : $this->config->getEntityAttributes($eavEntityType, new \Magento\Framework\DataObject($entityData));
  58. /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
  59. foreach ($attributes as $attribute) {
  60. if (!$attribute->isStatic() && $attribute->isScopeGlobal()) {
  61. $globalAttributes[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId();
  62. $attributesMap[$attribute->getAttributeId()] = $attribute->getAttributeCode();
  63. }
  64. }
  65. if ($globalAttributes) {
  66. $selects = [];
  67. foreach ($globalAttributes as $table => $attributeIds) {
  68. $select = $connection->select()
  69. ->from(
  70. ['t' => $table],
  71. ['value' => 't.value', 'attribute_id' => 't.attribute_id']
  72. )
  73. ->where($metadata->getLinkField() . ' = ?', $entityData[$metadata->getLinkField()])
  74. ->where('attribute_id' . ' in (?)', $attributeIds)
  75. ->where('store_id = ?', \Magento\Store\Model\Store::DEFAULT_STORE_ID);
  76. $selects[] = $select;
  77. }
  78. $unionSelect = new \Magento\Framework\DB\Sql\UnionExpression(
  79. $selects,
  80. \Magento\Framework\DB\Select::SQL_UNION_ALL
  81. );
  82. foreach ($connection->fetchAll($unionSelect) as $attributeValue) {
  83. $entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
  84. }
  85. }
  86. return $entityData;
  87. }
  88. }