I have previously already created a post with a code example that show how to create stores programmaticaly. Here is this previous post : https://www.addeos.com/magento-2-create-a-store-storegroup-website-programmaticaly
Here I present an other way of doing if using a native create processor present in Magento_Store module.
We are going to use a helper that contains the logic for creating new stores.
This helper holds the native processor. It passes a data table to it and execute its run method.
<?php
/**
* @author Didier Berlioz
* Copyright (c) Addeos All rights reserved.
*/
namespace Addeos\Store\Helper;
use Exception;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Store\Model\Config\Importer\Processor\Create;
use Magento\Store\Model\ResourceModel\Store as StoreModel;
use Psr\Log\LoggerInterface;
class Store extends AbstractHelper
{
/**
* @var Create
*/
private $storeCreateProcessor;
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var StoreModel
*/
private $storeResourceModel;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var ConfigInterface
*/
private $config;
/**
* Store constructor.
* @param Context $context
* @param Create $storeCreateProcessor
* @param StoreRepositoryInterface $storeRepository
* @param StoreModel $storeResourceModel
* @param LoggerInterface $logger
*/
public function __construct(
Context $context,
Create $storeCreateProcessor,
StoreRepositoryInterface $storeRepository,
StoreModel $storeResourceModel,
LoggerInterface $logger
) {
parent::__construct($context);
$this->storeCreateProcessor = $storeCreateProcessor;
$this->storeRepository = $storeRepository;
$this->storeResourceModel = $storeResourceModel;
$this->logger = $logger;
}
public function createStores($data)
{
try {
$this->storeCreateProcessor->run($data);
foreach ($data['stores'] as $storeData) {
$this->updateStore($storeData['code'], $storeData['group_id'], $storeData['website_id']);
}
} catch (Exception $e) {
$this->logger->error(__FILE__ . ' : ' . $e->getMessage());
}
}
private function updateStore($code, $groupId, $websiteId): void
{
try {
$store = $this->storeRepository->get($code);
$store->setStoreGroupId($groupId);
$store->setWebsiteId($websiteId);
$this->storeResourceModel->save($store);
} catch (Exception $e) {
$this->logger->error(__FILE__ . ' : ' . $e->getMessage());
}
}
And then an installer that will use that helper. What this installer does is basically building the data and passing it to the helper.
In that example, we are creating 2 new websites which each have a group and a store.
<?php
/**
* @author Didier Berlioz
* Copyright (c) Addeos All rights reserved.
*/
namespace Addeos\Store\Setup;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Addeos\Store\Helper\Store;
class InstallData implements InstallDataInterface
{
const FIRST_STORE_ID = 8;
const SECOND_STORE_ID = 9;
const FIRST_WEBSITE_ID = 6;
const SECOND_WEBSITE_ID = 7;
const FIRST_GROUP_ID = 6;
const SECOND_GROUP_ID = 7;
const FIRST_STORE_COUNTRY = 'DE';
const SECOND_STORE_COUNTRY = 'AT';
const FIRST_STORE_LOCALE = 'de_DE';
const SECOND_STORE_LOCALE = 'at_DE';
const ROOT_CATEGORY_ID = 2;
/**
* @var Store
*/
private $storeHelper;
/**
* InstallData constructor.
* @param Store $storeHelper
*/
public function __construct(Store $storeHelper)
{
$this->storeHelper = $storeHelper;
}
/**
* @inheritDoc
*/
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$this->storeHelper->createStores($this->getMyStoresData());
}
/**
* @return array
*/
private function getMyStoresData(): array
{
return [
'websites' => [
[
'website_id' => self::FIRST_WEBSITE_ID,
'code' => 'first_website_code',
'name' => 'First website name',
'sort_order' => 4,
'default_group_id' => self::FIRST_GROUP_ID,
'is_default' => 0,
],
[
'website_id' => self::SECOND_WEBSITE_ID,
'code' => 'second_website_code',
'name' => 'Second website name',
'sort_order' => 5,
'default_group_id' => self::SECOND_GROUP_ID,
'is_default' => 0,
],
],
'groups' => [
[
'group_id' => self::FIRST_GROUP_ID,
'website_id' => self::FIRST_WEBSITE_ID,
'code' => 'first_group_code',
'name' => 'First group name',
'root_category_id' => self::ROOT_CATEGORY_ID,
'default_store_id' => self::FIRST_STORE_ID,
],
[
'group_id' => self::SECOND_GROUP_ID,
'website_id' => self::SECOND_WEBSITE_ID,
'code' => 'second_group_code',
'name' => 'Second group name',
'root_category_id' => self::ROOT_CATEGORY_ID,
'default_store_id' => self::SECOND_STORE_ID,
],
],
'stores' => [
[
'store_id' => self::FIRST_STORE_ID,
'code' => 'first-store-code',
'website_id' => self::FIRST_WEBSITE_ID,
'group_id' => self::FIRST_GROUP_ID,
'name' => 'First store name',
'sort_order' => 0,
'is_active' => 0,
'locale' => self::FIRST_STORE_LOCALE,
'country' => self::FIRST_STORE_COUNTRY,
],
[
'store_id' => self::SECOND_STORE_ID,
'code' => 'second-store-code',
'website_id' => self::SECOND_WEBSITE_ID,
'group_id' => self::SECOND_GROUP_ID,
'name' => 'Second store name',
'sort_order' => 0,
'is_active' => 0,
'locale' => self::SECOND_STORE_LOCALE,
'country' => self::SECOND_STORE_COUNTRY,
],
],
];
}
}