Store Hierarchy

Magento implements a three-tier hierarchy that enables complex multi-store architectures. Understanding this hierarchy is critical because configuration scope, catalog assignment, and URL routing all depend on it.

WEBSITE (Top Level)
├── Owns payment methods, shipping methods, customer sharing
├── Base currency is set at website level
└── Multiple websites share the same Magento installation

STORE GROUP (Middle Level - also called "Store")
├── Owns the root category (catalog structure)
├── Groups store views for a single catalog
└── Multiple groups can exist under one website

STORE VIEW (Bottom Level)
├── Owns language/locale settings
├── Display currency configuration
├── Theme assignment
└── URL configuration and redirects
Terminology Confusion

The term "Store" is used inconsistently in Magento. In the admin UI, "Store" refers to a Store Group (middle tier), while "Store View" is the bottom tier. In code, StoreInterface represents a Store View. The database table store also represents Store Views, not Store Groups.

Scope Configuration System

Configuration values can be set at three scopes, with more specific scopes overriding less specific ones. The ScopeInterface defines the constants used throughout Magento for scope resolution.

Default
SCOPE_DEFAULT
Website
SCOPE_WEBSITE
Store View
SCOPE_STORE
// ScopeInterface constants interface ScopeInterface { const SCOPE_STORES = 'stores'; // Plural form const SCOPE_WEBSITES = 'websites'; // Plural form const SCOPE_GROUPS = 'groups'; // Plural form const SCOPE_STORE = 'store'; // Singular form const SCOPE_WEBSITE = 'website'; // Singular form const SCOPE_GROUP = 'group'; // Singular form }

Configuration Retrieval Pattern

// Getting scoped configuration $scopeConfig->getValue( 'general/locale/code', ScopeInterface::SCOPE_STORE, $storeCode // null = current store ); // isSetFlag for boolean configs $scopeConfig->isSetFlag( 'general/single_store_mode/enabled', ScopeInterface::SCOPE_STORE );

Core Service Interfaces

StoreManagerInterface
The most injected interface in Magento. Provides access to all store entities and manages current store context.
  • getStore($storeId = null)
  • getStores($withDefault, $codeKey)
  • getWebsite($websiteId = null)
  • getWebsites($withDefault, $codeKey)
  • getGroup($groupId = null)
  • getGroups($withDefault)
  • getDefaultStoreView()
  • setCurrentStore($store)
  • hasSingleStore()
  • isSingleStoreMode()
  • reinitStores()
StoreResolverInterface
Resolves the current store ID from URL path, GET parameters, or cookies. Called during application bootstrap.
  • getCurrentStoreId()
StoreRepositoryInterface
Repository for Store View entities. Provides CRUD operations with caching.
  • get($code)
  • getById($id)
  • getList()
  • getActiveStoreByCode($code)
  • getActiveStoreById($id)
  • clean()
WebsiteRepositoryInterface
Repository for Website entities. Includes default website resolution.
  • get($code)
  • getById($id)
  • getList()
  • getDefault()
  • clean()
GroupRepositoryInterface
Repository for Store Group entities. Links websites to their store groups.
  • get($id)
  • getList()
  • clean()
StoreCookieManagerInterface
Manages store code persistence in cookies for store switching functionality.
  • getStoreCodeFromCookie()
  • setStoreCookie($store)
  • deleteStoreCookie($store)

Database Schema

store_website

Column Type Description
website_id PK smallint Primary key, auto-increment
code varchar(32) Unique website code (e.g., "base", "b2b")
name varchar(64) Website display name
sort_order smallint Display sort order
default_group_id smallint Default store group ID
is_default smallint Whether this is the default website

store_group

Column Type Description
group_id PK smallint Primary key, auto-increment
website_id FK smallint References store_website.website_id
name varchar(255) Store group display name
root_category_id int Root category for this store's catalog
default_store_id smallint Default store view ID
code varchar(32) Unique store group code

store

Column Type Description
store_id PK smallint Primary key, auto-increment
code varchar(32) Unique store view code (e.g., "default", "french")
website_id FK smallint References store_website.website_id
group_id FK smallint References store_group.group_id
name varchar(255) Store view display name
sort_order smallint Display sort order
is_active smallint Whether store view is active

StoreManager Initialization

The StoreManager is the concrete implementation of StoreManagerInterface. It relies on several repositories and the StoreResolver to determine the current store context.

class StoreManager implements StoreManagerInterface { // Environment variable for run code (store/website code) const PARAM_RUN_CODE = 'MAGE_RUN_CODE'; // Environment variable for run type (store|website) const PARAM_RUN_TYPE = 'MAGE_RUN_TYPE'; // Config path for single store mode const XML_PATH_SINGLE_STORE_MODE_ENABLED = 'general/single_store_mode/enabled'; public function getStore($storeId = null) { // If no store ID, resolve from StoreResolver if (!isset($storeId)) { if (null === $this->currentStoreId) { Profiler::start('store.resolve'); $this->currentStoreId = $this->storeResolver->getCurrentStoreId(); Profiler::stop('store.resolve'); } $storeId = $this->currentStoreId; } // Return StoreInterface instance return is_numeric($storeId) ? $this->storeRepository->getById($storeId) : $this->storeRepository->get($storeId); } }
Performance Note

The getStore() method is called thousands of times per request. The result is cached in $currentStoreId after first resolution. Repository methods also cache their results to avoid repeated database queries.