Skip to content

Commit e7386e9

Browse files
committed
ACP2E-390: Website level customer attributes enabled for one website and disabled for other still shows enabled for both websites.
1 parent 302f6c5 commit e7386e9

File tree

2 files changed

+106
-16
lines changed

2 files changed

+106
-16
lines changed

app/code/Magento/Eav/Model/Config.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
99
use Magento\Eav\Model\Entity\Type;
10+
use Magento\Eav\Model\ResourceModel\Attribute\Collection;
1011
use Magento\Eav\Model\ResourceModel\Attribute\DefaultEntityAttributes\ProviderInterface;
1112
use Magento\Framework\App\Config\ScopeConfigInterface;
1213
use Magento\Framework\App\ObjectManager;
@@ -28,17 +29,19 @@ class Config
2829
/**#@+
2930
* EAV cache ids
3031
*/
31-
const ENTITIES_CACHE_ID = 'EAV_ENTITY_TYPES';
32-
const ATTRIBUTES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES';
33-
const ATTRIBUTES_CODES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES_CODES';
32+
public const ENTITIES_CACHE_ID = 'EAV_ENTITY_TYPES';
33+
public const ATTRIBUTES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES';
34+
public const ATTRIBUTES_CODES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES_CODES';
3435
/**#@-*/
3536

3637
/**
3738
* Xml path to caching user defined eav attributes configuration.
3839
*/
3940
private const XML_PATH_CACHE_USER_DEFINED_ATTRIBUTES = 'dev/caching/cache_user_defined_attributes';
4041

41-
/**#@-*/
42+
/**
43+
* @var array|null
44+
*/
4245
protected $_entityTypeData;
4346

4447
/**
@@ -574,6 +577,7 @@ public function getAttribute($entityType, $code)
574577
* @param array $systemAttributes
575578
* @return $this|bool|void
576579
* @throws LocalizedException
580+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
577581
*/
578582
private function initSystemAttributes($entityType, $systemAttributes)
579583
{
@@ -582,8 +586,9 @@ private function initSystemAttributes($entityType, $systemAttributes)
582586
if (!empty($this->isSystemAttributesLoaded[$entityTypeCode])) {
583587
return;
584588
}
585-
586-
$cacheKey = self::ATTRIBUTES_CACHE_ID . '-' . $entityTypeCode . '-preload';
589+
$attributeCollection = $this->_universalFactory->create($entityType->getEntityAttributeCollection());
590+
$websiteId = $attributeCollection instanceof Collection ? $this->getWebsiteId($attributeCollection) : 0;
591+
$cacheKey = self::ATTRIBUTES_CACHE_ID . '-' . $entityTypeCode . '-' . $websiteId . '-preload';
587592
if ($this->isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))) {
588593
$attributes = $this->serializer->unserialize($attributes);
589594
if ($attributes) {
@@ -598,9 +603,7 @@ private function initSystemAttributes($entityType, $systemAttributes)
598603
\Magento\Framework\Profiler::start('EAV: ' . __METHOD__, ['group' => 'EAV', 'method' => __METHOD__]);
599604

600605
/** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $attributes */
601-
$attributes = $this->_universalFactory->create(
602-
$entityType->getEntityAttributeCollection()
603-
)->setEntityTypeFilter(
606+
$attributes = $attributeCollection->setEntityTypeFilter(
604607
$entityType
605608
)->addFieldToFilter(
606609
'attribute_code',
@@ -762,16 +765,21 @@ public function getEntityAttributes($entityType, $object = null)
762765
return $this->attributesPerSet[$cacheKey];
763766
}
764767

765-
$attributesData = $this->isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))
766-
? $this->serializer->unserialize($attributes)
767-
: null;
768+
$attributeCollection = $this->_universalFactory->create($entityType->getEntityAttributeCollection());
769+
// If entity contains website-dependent attributes, the result should not be cached here.
770+
// Website in collection is resolved by StoreManager which causes incorrect entity attributes caching when
771+
// the entity is loaded from the backend first time after the cache cleanup.
772+
$isEntityWebsiteDependent = $attributeCollection instanceof Collection;
773+
$attributesData = null;
774+
if ($this->isCacheEnabled() && !$isEntityWebsiteDependent && ($attributes = $this->_cache->load($cacheKey))) {
775+
$attributesData = $this->serializer->unserialize($attributes);
776+
}
768777

769778
$attributes = [];
770779
if ($attributesData === null) {
771780
if ($attributeSetId) {
772-
$attributesData = $this->_universalFactory->create(
773-
$entityType->getEntityAttributeCollection()
774-
)->setEntityTypeFilter(
781+
$attributeCollection = $this->_universalFactory->create($entityType->getEntityAttributeCollection());
782+
$attributesData = $attributeCollection->setEntityTypeFilter(
775783
$entityType
776784
)->setAttributeSetFilter(
777785
$attributeSetId
@@ -783,7 +791,7 @@ public function getEntityAttributes($entityType, $object = null)
783791
$attributesData = $this->_attributeData[$entityType->getEntityTypeCode()];
784792
}
785793

786-
if ($this->isCacheEnabled()) {
794+
if ($this->isCacheEnabled() && !$isEntityWebsiteDependent) {
787795
$this->_cache->save(
788796
$this->serializer->serialize($attributesData),
789797
$cacheKey,
@@ -960,4 +968,15 @@ private function initAttributesFromCache(Type $entityType)
960968
}
961969
return false;
962970
}
971+
972+
/**
973+
* Returns website id.
974+
*
975+
* @param Collection $attributeCollection
976+
* @return int
977+
*/
978+
private function getWebsiteId(Collection $attributeCollection): int
979+
{
980+
return $attributeCollection->getWebsite() ? (int)$attributeCollection->getWebsite()->getId() : 0;
981+
}
963982
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Model;
9+
10+
use Magento\Customer\Api\CustomerMetadataInterface;
11+
use Magento\Eav\Model\Config;
12+
use Magento\Store\Model\StoreManagerInterface;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class CustomerSystemAttributeTest extends TestCase
17+
{
18+
/**
19+
* @var StoreManagerInterface
20+
*/
21+
private $storeManager;
22+
23+
/**
24+
* @inheritdoc
25+
*/
26+
protected function setUp(): void
27+
{
28+
$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
29+
}
30+
31+
/**
32+
* Verifies that customer system attributes are cached per website.
33+
*
34+
* @return void
35+
* @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php
36+
*/
37+
public function testCustomerSystemAttributePerWebsite(): void
38+
{
39+
$systemAttributeCode = 'taxvat';
40+
$entityType = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER;
41+
$currentStore = $this->storeManager->getStore();
42+
$config = Bootstrap::getObjectManager()->get(Config::class);
43+
44+
$attribute = $config->getAttribute($entityType, $systemAttributeCode);
45+
$attribute->setData('scope_is_visible', '0');
46+
$attribute->save();
47+
48+
$secondWebsite = $this->storeManager->getWebsite('test');
49+
$attribute->setWebsite($secondWebsite->getId());
50+
$attribute->setData('scope_is_visible', '1');
51+
$attribute->save();
52+
53+
$this->storeManager->setCurrentStore('fixture_second_store');
54+
$config = Bootstrap::getObjectManager()->create(Config::class);
55+
$scopeAttribute = $config->getAttribute($entityType, $systemAttributeCode);
56+
$this->assertEquals(
57+
1,
58+
$scopeAttribute->getData('scope_is_visible'),
59+
'Attribute visibility doesn\'t correspond the scope'
60+
);
61+
62+
$this->storeManager->setCurrentStore($currentStore);
63+
$config = Bootstrap::getObjectManager()->create(Config::class);
64+
$scopeAttribute = $config->getAttribute($entityType, $systemAttributeCode);
65+
$this->assertEquals(
66+
0,
67+
$scopeAttribute->getData('scope_is_visible'),
68+
'Attribute visibility doesn\'t correspond the scope'
69+
);
70+
}
71+
}

0 commit comments

Comments
 (0)