8

I'd like to know if it's possible (if so, how) to programmatically create a new customer group using the Magento 2 framework. Ideally I'd like to do this in a setup class.

Looking at the GroupRegistry class, I only see a retrieve() and remove() method. The class also doesn't extend anything so wouldn't inherit these methods - so I know this isn't the right place to look.

Of course, I'm probably looking in the wrong place or misunderstand the concept of how it works.

Do I even need to bother trying to find the class that will handle this, or should I just specify a GroupRepositoryInterface in the constructor of the class and assume it'll be provided by the object manager? The interface provides the save() method, which is what I need.

This is what I'm thinking so far:

namespace MyCompany\MyModule\Setup;

use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Model\GroupFactory;

class InstallData implements InstallDataInterface
{
    protected $groupFactory;
    protected $groupRepository;

    /**
     * I'd like a customer group factory and a customer group repository
     */
    public function __construct(
        GroupFactory $groupFactory,
        GroupRepositoryInterface $groupRepository
    ) {
        $this->groupFactory = $groupFactory;
        $this->groupRepository = $groupRepository;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        // Create the new group
        $group = $this->groupFactory->create();

        $group->setCode('My New Group');
        $group->setTaxClassId(3); // magic number is only for demo..

        // Use the group repository to save it
        $this->groupRepository->save($group);

        $setup->endSetup();
    }
}

Am I close? If I run this, I get the following exception:

Argument 1 passed to Magento\Customer\Model\ResourceModel\GroupRepository\Interceptor::save() must implement interface Magento\Customer\Api\Data\GroupInterface, instance of Magento\Customer\Model\Group\Interceptor given

2
  • how many groups are you creating.
    – encodes
    Commented Feb 24, 2016 at 13:38
  • @encodes in this scenario it was one, but assume any number - question was around the concept of creating them in general
    – scrowler
    Commented Feb 24, 2016 at 20:49

6 Answers 6

16

May as well answer this since I figured it out.

The problem with my example above is that I was trying to use the GroupRepository to push the new model to the database.

Instead, I should have just used $group->save() on the model returned by the GroupFactory:

<?php
namespace MyCompany\MyModule\Setup;

use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\GroupFactory;

class InstallData implements InstallDataInterface
{
    protected $groupFactory;

    /**
     * I'd like a customer group factory please Sir!
     */
    public function __construct(GroupFactory $groupFactory) {
        $this->groupFactory = $groupFactory;
    }

    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();

        // Create the new group
        /** @var \Magento\Customer\Model\Group $group */
        $group = $this->groupFactory->create();
        $group
            ->setCode('My New Group')
            ->setTaxClassId(3) // magic numbers OK, core installers do it?!
            ->save();

        $setup->endSetup();
    }
}
5
  • I am also facing the same issue. But i am already saving the group without repository. But when i try to inspect the code Magento gives the warning that i am using the deprecated function save. And during taking the Magento U courses they explicitly mention in future save methods of the models can be removed. So is it fine to use the save method of the group instead save using repository?
    – Abbas
    Commented Jan 31, 2017 at 0:59
  • Hi @Abbas, the public API may have changed since I wrote this post - you probably know better than I do! If you could post a link to any references you have about ->save() being deprecated, that'd be awesome.
    – scrowler
    Commented Jan 31, 2017 at 1:24
  • 1
    There's a syntax error with your code, you write ->setCode('My New Group'); then have ->setTaxClassId(3) on the next line. The semicolon closes the $group variable, but then no variable is defined for the next line. You should take the semicolon out - I'll make an edit if I can for you.
    – hazrpg
    Commented Sep 4, 2017 at 14:50
  • The save is deprecated Commented Sep 10, 2018 at 8:39
  • @MohamedElMrabet yes, see the answer below
    – scrowler
    Commented Sep 10, 2018 at 9:04
9

Save method is deprecated in Magento 2 try this code:

<?php
/**
 * Copyright © 2018 MyCompany. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace MyCompany\MyModule\Setup;

use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Customer\Api\Data\GroupInterfaceFactory;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

/**
 * Class InstallData
 *
 * @package MyCompany\MyModule\Setup
 */
class InstallData implements InstallDataInterface
{
    /**
     * @var GroupInterfaceFactory
     */
    private $groupFactory;

    /**
     * @var GroupRepositoryInterface
     */
    private $groupRepository;

    /**
     * InstallData constructor.
     *
     * @param GroupInterfaceFactory $groupFactory
     * @param GroupRepositoryInterface $groupRepository
     */
    public function __construct(
        GroupInterfaceFactory $groupFactory,
        GroupRepositoryInterface $groupRepository
    ) {
        $this->groupFactory = $groupFactory;
        $this->groupRepository = $groupRepository;
    }

    /**
     * Installs data for a module
     *
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     * @return void
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        try {
            // Create the new group
            /** @var \Magento\Customer\Model\Group $group */
            $group = $this->groupFactory->create();
            $group
                ->setCode('My New Group')
                ->setTaxClassId(3);
            $this->groupRepository->save($group);
        } catch (\Exception $e) {

        }

        $setup->endSetup();
    }
}
4
  • This doesn't provide anything more than this existing answer does
    – scrowler
    Commented Sep 10, 2018 at 9:05
  • Ok but the code is more clear, i dont see this answer before i write mine this code i just tested in personal project Commented Sep 10, 2018 at 9:33
  • @MohamedElMrabet, saying Save method is deprecated but you are using still save() in your answer Commented Feb 21, 2019 at 7:18
  • He means the save method of groupFactory not of groupRepository
    – roman204
    Commented Jul 19, 2021 at 12:47
7

Since the version 2.2.1 the use of the ->save() method from the Magento\Customer\Model\Group implementations has been deprecated.

Instead, you should use:

use Magento\Customer\Api\Data\GroupInterfaceFactory;
use Magento\Customer\Api\GroupRepositoryInterface;

instead

use Magento\Customer\Model\GroupFactory;

Using Robbie Averill solution as a baseline: https://magento.stackexchange.com/a/93789/15530

Pass those classes to the constructor like:

public function __construct(
        GroupInterfaceFactory $groupFactory,
        GroupRepositoryInterface $groupInterface) {
        $this->groupFactory = $groupFactory;
        $this->groupInterface = $groupInterface;
}

And then just use it as per this example: $this->groupInterface->save($group);

Where group is created using the factory creator like: $group = $this->groupFactory->create();

0

You can create a single/multiples customer groups by below script code

File Path : app/code/MyCompany/MyModule/Setup/InstallData.php

<?php
namespace MyCompany\MyModule\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Customer\Model\GroupFactory;

class InstallData implements InstallDataInterface
{

    protected $groupFactory;

    /**
     * Constructor
     *
     * @param Magento\Customer\Model\GroupFactory $groupFactory
     */
    public function __construct(

        GroupFactory $groupFactory
    ) {

        $this->groupFactory = $groupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {


        /** Create a customer Group */
        /** @var \Magento\Customer\Model\Group $group */
        $setup->startSetup();

    /* Create a multiple customer group */
        $setup->getConnection()->insertForce(
            $setup->getTable('customer_group'),
            ['customer_group_code' => 'YourNewCustomerGroup', 'tax_class_id' => 3]
        );
        $setup->getConnection()->insertForce(
            $setup->getTable('customer_group'),
            ['customer_group_code' => 'YourNewCustomerGroup', 'tax_class_id' => 3]
        );

        $setup->endSetup();
    }
}
2
  • This is not the incorrect answer, This is just the core magento way to resolved the question. So down-vote such answer is not the proper way. Commented Sep 29, 2017 at 7:44
  • See my answer using the repository $this->groupRepository->save($group); Commented Sep 10, 2018 at 8:44
0

There is no way to use repository save() as magento recommend, because Group class is not implement GroupInterface and you have error:

Fatal error: Uncaught TypeError: Argument 1 passed to Magento\Customer\Model\ResourceModel\GroupRepository\Interceptor::save() must implement interface Magento\Customer\Api\Data\GroupInterface, instance of Magento\Customer\Model\Group\Interceptor given

You still have to use standard save() in GroupModel. Example code:

$newCustomerGroup = $this->groupFactory->create();
$newCustomerGroup->setCode('Test customer group');
$newCustomerGroup->setTaxClassId(\Magento\Customer\Model\ResourceModel\GroupRepository::DEFAULT_TAX_CLASS_ID);
$newCustomerGroup->save();
-1

Instead of hardwrite 3 for tax_class_id, you can use constant for default tax id : \Magento\Customer\Api\GroupRepositoryInterface::DEFAULT_TAX_CLASS_ID

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.