【会員グループ管理プラグイン】特定の商品を購入すると自動で会員に会員グループを付与する方法

会員グループ管理プラグインで特定の商品を購入すると自動で会員に会員グループを付与する方法です。

はじめに

以下のカスタマイズを動作させるためには、会員グループ管理プラグイン をインストール・有効化する必要があります。

今回の実装で、定期購入商品(継続課金用)を購入したらプレミアム会員になってプレミアム会員価格(※会員グループ管理::会員グループ価格管理アドオン for EC-CUBE4が必要です。)で購入できたり送料が無料になるなどの特典が受けられるようにするカスタマイズを想定しています。

ただし定期購入商品をキャンセルした場合、通常会員に戻すといった処理は考えられていません。

Productエンティティに自動登録する会員グループを保存する項目を追加

まずは以下のようにProductエンティティに自動登録する会員グループを保存する項目を追加するProductTraitを作成します。

<?php
/**
 * This file is part of CustomerGroupProduct
 *
 * Copyright(c) Akira Kurozumi <info@a-zumi.net>
 *
 * https://a-zumi.net
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Plugin\CustomerGroupProduct\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation\EntityExtension;
use Plugin\CustomerGroup\Entity\Group;

/**
 * Class ProductTrait
 * @package Plugin\CustomerGroupProduct\Entity
 *
 * @EntityExtension("Eccube\Entity\Product")
 */
trait ProductTrait
{
    /**
     * @var Group
     *
     * @ORM\ManyToOne(targetEntity="Plugin\CustomerGroup\Entity\Group")
     * @ORM\JoinColumn(referencedColumnName="id")
     */
    private $registerGroup;

    /**
     * @return Group|null
     */
    public function getRegisterGroup(): ?Group
    {
        return $this->registerGroup;
    }

    /**
     * @return bool
     */
    public function hasRegisterGroup(): bool
    {
        return $this->registerGroup instanceof Group;
    }

    /**
     * @param Group $registerGroup
     * @return $this
     */
    public function setRegisterGroup(Group $registerGroup): self
    {
        $this->registerGroup = $registerGroup;

        return $this;
    }
}

商品登録ページに自動登録する会員グループを選択する項目を追加

次に以下のよう商品登録ページに自動登録する会員グループを選択する項目を追加するためにProductTypeを拡張します。

<?php
/**
 * This file is part of CustomerGroupProduct
 *
 * Copyright(c) Akira Kurozumi <info@a-zumi.net>
 *
 * https://a-zumi.net
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Plugin\CustomerGroupProduct\Form\Extension\Admin;


use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\EntityRepository;
use Eccube\Form\Type\Admin\ProductType;
use Plugin\CustomerGroup\Entity\Group;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;

class ProductTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('registerGroup', EntityType::class, [
                'label' => '自動登録する会員グループ',
                'class' => Group::class,
                'expanded' => false,
                'multiple' => false,
                'required' => false,
                'placeholder' => 'common.select__unspecified',
                'eccube_form_options' => [
                    'auto_render' => true,
                ],
                'choice_label' => function (Group $group) {
                    return $group->getName() . '[管理名:' . $group->getBackendName() .']';
                },
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('g')
                        ->orderBy('g.sortNo', Criteria::ASC);
                }
            ]);
    }

    /**
     * @return string
     */
    public function getExtendedType(): string
    {
        return ProductType::class;
    }

    /**
     * @return iterable
     */
    public static function getExtendedTypes(): iterable
    {
        yield ProductType::class;
    }
}

購入完了ページで会員に会員グループを付与する処理

購入した商品のなかに「自動登録する会員グループ」が設定された商品があった場合、購入完了ページで会員に会員グループを付与する処理を実装します。

すでに会員に別の会員グループが設定されていた場合、その会員グループからは外れて商品に設定されている会員グループが付与されます。

<?php
/**
 * This file is part of CustomerGroupProduct
 *
 * Copyright(c) Akira Kurozumi <info@a-zumi.net>
 *
 * https://a-zumi.net
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Plugin\CustomerGroupProduct\EventListener;


use Doctrine\ORM\EntityManagerInterface;
use Eccube\Entity\Customer;
use Eccube\Entity\Order;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ShoppingCompleteListener implements EventSubscriberInterface
{
    /**
     * @var EntityManagerInterface
     */
    private $entityManager;

    /**
     * ShoppingCompleteListener constructor.
     * @param EntityManagerInterface $entityManager
     */
    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    /**
     * @return string[]
     */
    public static function getSubscribedEvents(): array
    {
        return [
            EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE => 'onFrontShoppingCompleteInitialize'
        ];
    }

    /**
     * @param EventArgs $event
     */
    public function onFrontShoppingCompleteInitialize(EventArgs $event): void
    {
        /** @var Order $order */
        $order = $event->getArgument('Order');
        $customer = $order->getCustomer();

        if ($customer instanceof Customer) {
            foreach ($order->getOrderItems() as $orderItem) {
                if ($orderItem->isProduct()) {
                    $product = $orderItem->getProduct();
                    if ($product->hasRegisterGroup()) {
                        $customer->getGroups()->clear();
                        $customer->addGroup($product->getRegisterGroup());
                    }
                }
            }
            $this->entityManager->persist($customer);
            $this->entityManager->flush();
        }
    }
}

以上で完成です。

プラグイン

プラグイン化したのでこちらもご参考ください。

会員グループ管理::会員グループ登録商品アドオン for EC-CUBE4

お気軽にコメントをどうぞ