diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index ac304017f581b..043f8c8977bec 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -74,9 +74,9 @@ class StoreManager implements protected $currentStoreId = null; /** - * Flag that shows that system has only one store view + * Flag that shows that system has only one store view; null is used as the cache sentinel. * - * @var bool + * @var bool|null */ protected $_hasSingleStore; @@ -137,8 +137,11 @@ public function setIsSingleStoreModeAllowed($value) */ public function hasSingleStore() { - // TODO: MAGETWO-39902 add cache, move value to consts - return $this->isSingleStoreAllowed && count($this->getStores(true)) < 3; + if ($this->_hasSingleStore === null) { + $this->_hasSingleStore = $this->isSingleStoreAllowed && count($this->getStores(true)) < 3; + } + + return $this->_hasSingleStore; } /** @@ -237,6 +240,7 @@ public function getWebsites($withDefault = false, $codeKey = false) public function reinitStores() { $this->currentStoreId = null; + $this->_hasSingleStore = null; $this->cache->clean( CacheConstants::CLEANING_MODE_MATCHING_ANY_TAG, [StoreResolver::CACHE_TAG, Store::CACHE_TAG, Website::CACHE_TAG, Group::CACHE_TAG] @@ -340,5 +344,6 @@ public function __debugInfo() public function _resetState(): void { $this->currentStoreId = null; + $this->_hasSingleStore = null; } } diff --git a/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php b/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php index 88ec1d48eb0ed..d55d0e95de931 100644 --- a/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/StoreManagerTest.php @@ -139,6 +139,32 @@ public function testReinitStores() $this->model->reinitStores(); } + public function testHasSingleStoreIsMemoizedAndReinitialized(): void + { + $defaultStoreMock = $this->getMockForStoreInterfaceClass(0, 'default'); + $storeMock = $this->getMockForStoreInterfaceClass(1, 'first_store'); + + $this->storeRepositoryMock->expects($this->exactly(2)) + ->method('getList') + ->willReturn([$defaultStoreMock, $storeMock]); + $this->cache->expects($this->once())->method('clean')->with( + CacheConstants::CLEANING_MODE_MATCHING_ANY_TAG, + [StoreResolver::CACHE_TAG, Store::CACHE_TAG, Website::CACHE_TAG, Group::CACHE_TAG] + ); + $this->scopeConfig->expects($this->once())->method('clean'); + $this->storeRepositoryMock->expects($this->once())->method('clean'); + $this->websiteRepository->expects($this->once())->method('clean'); + $this->groupRepository->expects($this->once())->method('clean'); + + $this->assertTrue($this->model->hasSingleStore()); + $this->assertTrue($this->model->hasSingleStore()); + + $this->model->reinitStores(); + + $this->assertTrue($this->model->hasSingleStore()); + $this->assertTrue($this->model->hasSingleStore()); + } + #[DataProvider('getStoresDataProvider')] public function testGetStores($storesList, $withDefault, $codeKey, $expectedStores) {