├── .gitignore ├── registration.php ├── etc ├── module.xml └── di.xml ├── composer.json ├── LICENSE ├── Model ├── StoreCreator.php ├── WebsiteCreator.php └── StoreViewCreator.php ├── Console └── Command │ ├── CreateStore.php │ ├── CreateWebsite.php │ └── CreateStoreView.php └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element119/module-store-entity-creator", 3 | "type": "magento2-module", 4 | "description": "A Magento 2 CLI utility to allow developers to create new websites, stores, and store views.", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "element119", 9 | "email": "hello@element119.co.uk" 10 | } 11 | ], 12 | "require": { 13 | "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", 14 | "magento/module-store": "^100.0.2 || ^101.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Element119\\StoreEntityCreator\\": "" 19 | }, 20 | "files": [ 21 | "registration.php" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 14 | Element119\StoreEntityCreator\Console\Command\CreateWebsite 15 | 16 | 17 | Element119\StoreEntityCreator\Console\Command\CreateStore 18 | 19 | 20 | Element119\StoreEntityCreator\Console\Command\CreateStoreView 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 element119 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Model/StoreCreator.php: -------------------------------------------------------------------------------- 1 | storeFactory = $storeFactory; 32 | $this->storeResourceModel = $storeResourceModel; 33 | } 34 | 35 | /** 36 | * @param array $data 37 | * @return Store 38 | * @throws Exception 39 | * @throws AlreadyExistsException 40 | */ 41 | public function create(array $data): Store 42 | { 43 | /** @var Store $store */ 44 | $store = $this->storeFactory->create(); 45 | 46 | $store->setData($data); 47 | $this->storeResourceModel->save($store); 48 | 49 | return $store; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Model/WebsiteCreator.php: -------------------------------------------------------------------------------- 1 | websiteFactory = $websiteFactory; 32 | $this->websiteResourceModel = $websiteResourceModel; 33 | } 34 | 35 | /** 36 | * @param array $data 37 | * @return Website 38 | * @throws Exception 39 | * @throws AlreadyExistsException 40 | */ 41 | public function create(array $data): Website 42 | { 43 | /** @var Website $website */ 44 | $website = $this->websiteFactory->create(); 45 | 46 | $website->setData($data); 47 | $this->websiteResourceModel->save($website); 48 | 49 | return $website; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Model/StoreViewCreator.php: -------------------------------------------------------------------------------- 1 | storeViewFactory = $storeViewFactory; 33 | $this->storeViewResourceModel = $storeViewResourceModel; 34 | } 35 | 36 | /** 37 | * @param array $data 38 | * @return StoreView 39 | * @throws Exception 40 | * @throws AlreadyExistsException 41 | */ 42 | public function create(array $data): StoreView 43 | { 44 | /** @var StoreView $storeView */ 45 | $storeView = $this->storeViewFactory->create(); 46 | 47 | $storeView->setData($data); 48 | $this->storeViewResourceModel->save($storeView); 49 | 50 | return $storeView; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Console/Command/CreateStore.php: -------------------------------------------------------------------------------- 1 | storeCreator = $storeCreator; 32 | } 33 | 34 | protected function configure() 35 | { 36 | $this->setName('app:store:create') 37 | ->setDescription('Create a new store.') 38 | ->addArgument( 39 | StoreCreator::STORE_CODE, 40 | InputArgument::REQUIRED, 41 | 'New store code.' 42 | )->addArgument( 43 | StoreCreator::STORE_NAME, 44 | InputArgument::REQUIRED, 45 | 'New store name.' 46 | )->addArgument( 47 | StoreCreator::STORE_WEBSITE_ID, 48 | InputArgument::REQUIRED, 49 | 'ID of the website to add the new store to.' 50 | )->addArgument( 51 | StoreCreator::STORE_ROOT_CATEGORY_ID, 52 | InputArgument::REQUIRED, 53 | 'New store root category ID.' 54 | )->addOption( 55 | self::INPUT_OPTION_DEFAULT_STORE_VIEW_ID, 56 | null, 57 | InputOption::VALUE_REQUIRED, 58 | 'Default store view ID for new store.' 59 | ); 60 | } 61 | 62 | protected function execute(InputInterface $input, OutputInterface $output): int 63 | { 64 | $storeData = [ 65 | StoreCreator::STORE_NAME => $input->getArgument(StoreCreator::STORE_NAME), 66 | StoreCreator::STORE_CODE => $input->getArgument(StoreCreator::STORE_CODE), 67 | StoreCreator::STORE_WEBSITE_ID => $input->getArgument(StoreCreator::STORE_WEBSITE_ID), 68 | StoreCreator::STORE_ROOT_CATEGORY_ID => $input->getArgument(StoreCreator::STORE_ROOT_CATEGORY_ID), 69 | StoreCreator::STORE_DEFAULT_STORE_ID => $input->getOption(self::INPUT_OPTION_DEFAULT_STORE_VIEW_ID), 70 | ]; 71 | 72 | try { 73 | $this->storeCreator->create($storeData); 74 | } catch (Exception $e) { 75 | $output->writeln('Failed to create new store:'); 76 | $output->writeln($e->getMessage()); 77 | 78 | return CLI::RETURN_FAILURE; 79 | } 80 | 81 | $output->writeln('Store created.'); 82 | 83 | return Cli::RETURN_SUCCESS; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Console/Command/CreateWebsite.php: -------------------------------------------------------------------------------- 1 | websiteCreator = $websiteCreator; 34 | } 35 | 36 | protected function configure() 37 | { 38 | $this->setName('app:website:create') 39 | ->setDescription('Create a new website.') 40 | ->addArgument( 41 | WebsiteCreator::WEBSITE_CODE, 42 | InputArgument::REQUIRED, 43 | 'New website code.' 44 | )->addArgument( 45 | WebsiteCreator::WEBSITE_NAME, 46 | InputArgument::REQUIRED, 47 | 'New website name.' 48 | )->addOption( 49 | self::INPUT_OPTION_DEFAULT_STORE_ID, 50 | null, 51 | InputOption::VALUE_REQUIRED, 52 | 'Default store ID for new website.' 53 | )->addOption( 54 | self::INPUT_OPTION_SORT_ORDER, 55 | null, 56 | InputOption::VALUE_REQUIRED, 57 | 'New website sort order.' 58 | )->addOption( 59 | self::INPUT_OPTION_IS_DEFAULT, 60 | null, 61 | InputOption::VALUE_NONE, 62 | 'Sets the new website as the default website.' 63 | ); 64 | } 65 | 66 | protected function execute(InputInterface $input, OutputInterface $output): int 67 | { 68 | $websiteData = [ 69 | WebsiteCreator::WEBSITE_NAME => $input->getArgument(WebsiteCreator::WEBSITE_NAME), 70 | WebsiteCreator::WEBSITE_CODE => $input->getArgument(WebsiteCreator::WEBSITE_CODE), 71 | WebsiteCreator::WEBSITE_DEFAULT_STORE => $input->getOption(self::INPUT_OPTION_DEFAULT_STORE_ID), 72 | WebsiteCreator::WEBSITE_IS_DEFAULT => $input->getOption(self::INPUT_OPTION_IS_DEFAULT), 73 | WebsiteCreator::WEBSITE_SORT_ORDER => $input->getOption(self::INPUT_OPTION_SORT_ORDER) ?? 0, 74 | ]; 75 | 76 | try { 77 | $this->websiteCreator->create($websiteData); 78 | } catch (Exception $e) { 79 | $output->writeln('Failed to create new website:'); 80 | $output->writeln($e->getMessage()); 81 | 82 | return CLI::RETURN_FAILURE; 83 | } 84 | 85 | $output->writeln('Website created.'); 86 | 87 | return Cli::RETURN_SUCCESS; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Console/Command/CreateStoreView.php: -------------------------------------------------------------------------------- 1 | storeViewCreator = $storeViewCreator; 38 | $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class); 39 | } 40 | 41 | protected function configure() 42 | { 43 | $this->setName('app:store-view:create') 44 | ->setDescription('Create a new store view.') 45 | ->addArgument( 46 | StoreViewCreator::STORE_VIEW_CODE, 47 | InputArgument::REQUIRED, 48 | 'New store view code.' 49 | )->addArgument( 50 | StoreViewCreator::STORE_VIEW_NAME, 51 | InputArgument::REQUIRED, 52 | 'New store view name.' 53 | )->addArgument( 54 | self::INPUT_ARGUMENT_STORE_ID, 55 | InputArgument::REQUIRED, 56 | 'ID of the store to add the new store view to.' 57 | )->addOption( 58 | self::INPUT_OPTION_DISABLED, 59 | null, 60 | InputOption::VALUE_NONE, 61 | 'Disable the new store view.' 62 | )->addOption( 63 | self::INPUT_OPTION_SORT_ORDER, 64 | null, 65 | InputOption::VALUE_REQUIRED, 66 | 'New store view sort order.' 67 | ); 68 | } 69 | 70 | protected function execute(InputInterface $input, OutputInterface $output): int 71 | { 72 | $storeViewData = [ 73 | StoreViewCreator::STORE_VIEW_NAME => $input->getArgument(StoreViewCreator::STORE_VIEW_NAME), 74 | StoreViewCreator::STORE_VIEW_CODE => $input->getArgument(StoreViewCreator::STORE_VIEW_CODE), 75 | StoreViewCreator::STORE_VIEW_STORE_ID => $input->getArgument(self::INPUT_ARGUMENT_STORE_ID), 76 | StoreViewCreator::STORE_VIEW_SORT_ORDER => $input->getOption(self::INPUT_OPTION_SORT_ORDER), 77 | StoreViewCreator::STORE_VIEW_STATUS => !$input->getOption(self::INPUT_OPTION_DISABLED), 78 | StoreViewCreator::STORE_VIEW_WEBSITE_ID => $this->getWebsiteId( 79 | (int)$input->getArgument(self::INPUT_ARGUMENT_STORE_ID) 80 | ), 81 | ]; 82 | 83 | try { 84 | $this->storeViewCreator->create($storeViewData); 85 | } catch (Exception $e) { 86 | $output->writeln('Failed to create new store view:'); 87 | $output->writeln($e->getMessage()); 88 | 89 | return CLI::RETURN_FAILURE; 90 | } 91 | 92 | $output->writeln('Store view created.'); 93 | 94 | return Cli::RETURN_SUCCESS; 95 | } 96 | 97 | private function getWebsiteId(int $storeId): int 98 | { 99 | return (int)$this->storeManager->getGroup($storeId)->getWebsiteId(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

element119 | Store Entity Creator

2 | 3 | ## 📝 Features 4 | ✔️ Create store entities (websites, stores, and store views) using the Magento CLI 5 | 6 | ✔️ Theme agnostic 7 | 8 | ✔️ Built in accordance with Magento best practises 9 | 10 | ✔️ Seamless integration with Magento 11 | 12 | ✔️ Built with developers and extensibility in mind to make customisations as easy as possible 13 | 14 | ✔️ Installable via Composer 15 | 16 |
17 | 18 | ## 🔌 Installation 19 | Run the following command to *install* this module: 20 | ```bash 21 | composer require element119/module-store-entity-creator 22 | php bin/magento setup:upgrade 23 | ``` 24 | 25 |
26 | 27 | ## ⏫ Updating 28 | Run the following command to *update* this module: 29 | ```bash 30 | composer update element119/module-store-entity-creator 31 | php bin/magento setup:upgrade 32 | ``` 33 | 34 |
35 | 36 | ## ❌ Uninstallation 37 | Run the following command to *uninstall* this module: 38 | ```bash 39 | composer remove element119/module-store-entity-creator 40 | php bin/magento setup:upgrade 41 | ``` 42 | 43 |
44 | 45 | ## 📚 User Guide 46 | ### Website Creation - `app:website:create` 47 | ``` 48 | Description: 49 | Create a new website. 50 | 51 | Usage: 52 | app:website:create [options] [--] 53 | 54 | Arguments: 55 | code New website code. 56 | name New website name. 57 | 58 | Options: 59 | --default-store-id=DEFAULT-STORE-ID Default store ID for new website. 60 | --sort-order=SORT-ORDER New website sort order. 61 | --is-default Sets the new website as the default website. 62 | -h, --help Display help for the given command. When no command is given display help for the list command 63 | -q, --quiet Do not output any message 64 | -V, --version Display this application version 65 | --ansi|--no-ansi Force (or disable --no-ansi) ANSI output 66 | -n, --no-interaction Do not ask any interactive question 67 | -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug 68 | ``` 69 | 70 | ### Store Creation - `app:store:create` 71 | ``` 72 | Description: 73 | Create a new store. 74 | 75 | Usage: 76 | app:store:create [options] [--] 77 | 78 | Arguments: 79 | code New store code. 80 | name New store name. 81 | website_id ID of the website to add the new store to. 82 | root_category_id New store root category ID. 83 | 84 | Options: 85 | --default-store-view-id=DEFAULT-STORE-VIEW-ID Default store view ID for new store. 86 | -h, --help Display help for the given command. When no command is given display help for the list command 87 | -q, --quiet Do not output any message 88 | -V, --version Display this application version 89 | --ansi|--no-ansi Force (or disable --no-ansi) ANSI output 90 | -n, --no-interaction Do not ask any interactive question 91 | -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug 92 | ``` 93 | 94 | ### Store View Creation - `app:store-view:create` 95 | ``` 96 | Description: 97 | Create a new store view. 98 | 99 | Usage: 100 | app:store-view:create [options] [--] 101 | 102 | Arguments: 103 | code New store view code. 104 | name New store view name. 105 | store_id ID of the store to add the new store view to. 106 | 107 | Options: 108 | --disabled Disable the new store view. 109 | --sort-order=SORT-ORDER New store view sort order. 110 | -h, --help Display help for the given command. When no command is given display help for the list command 111 | -q, --quiet Do not output any message 112 | -V, --version Display this application version 113 | --ansi|--no-ansi Force (or disable --no-ansi) ANSI output 114 | -n, --no-interaction Do not ask any interactive question 115 | -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug 116 | ``` 117 | --------------------------------------------------------------------------------