Blog スタッフブログ

EC-CUBE システム開発

[EC-CUBE]EC-CUBE4で会員登録のバリデーション追加

システム開発担当のTFです。

会員登録時の各種項目に重複チェックのバリデーションを追加する方法。

※EC-CUBE4系統対応

やり方

  • CustomerTraitを作成し、loadValidatorMetadataで重複チェックを行う
  • Proxyを作成し、CustomerTraitを読み込む
  • 作成されたCustomerのproxyからloadValidatorMetadataをコメントアウトする(こちらが優先されるようでCustomerTrait側が呼ばれなかったため)
  • EntryTypeExtentionを作成し、細かなバリデーションを行う
  • キャッシュを削除する

参考

  EC-CUBE4系の商品コード重複登録エラーを実装したい
  【EC-CUBE4】商品規格に項目を追加し、バリデーションを入れる
  会員の住所に国を追加したい

サンプル

<?php

namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Annotation as Eccube;
use Eccube\Annotation\EntityExtension;

use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Mapping\ClassMetadata;

/**
  * @EntityExtension("Eccube\Entity\Customer")
 */
trait CustomerTrait
{
	public static function loadValidatorMetadata(ClassMetadata $metadata)
	{
		// Customerのデフォルトで入っているemaiの重複チェック
		$metadata->addConstraint(new UniqueEntity([
			'fields' => 'email',
			'message' => 'form_error.customer_already_exists',
			'repositoryMethod' => 'getNonWithdrawingCustomers',
		]));
		
		// 電話番号の重複チェック
		$metadata->addConstraint(new UniqueEntity([
			'fields' => 'phone_number',
			'message' => '登録済みの電話番号です',
			'repositoryMethod' => 'getNonWithdrawingCustomers',
		]));
	}
}
// Proxy作成
php bin/console eccube:generate:proxies
<?php

namespace Eccube\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Mapping\ClassMetadata;

    class Customer extends \Eccube\Entity\AbstractEntity implements UserInterface
    {
	// 追加される
    use  \Customize\Entity\CustomerTrait;
	
	// 省略
	
	// コメントアウトをする(CustomerTraitよりこちらが優先された為)
	/*
	public static function loadValidatorMetadata(ClassMetadata $metadata)
	{
		$metadata->addConstraint(new UniqueEntity([
			'fields' => 'email',
			'message' => 'form_error.customer_already_exists',
			'repositoryMethod' => 'getNonWithdrawingCustomers',
		]));
	}
	*/
	
	// 省略
	
	}
<?php

namespace Customize\Form\Extension;

use Doctrine\ORM\EntityManagerInterface;
use Eccube\Common\EccubeConfig;
use Eccube\Form\Type\Front\EntryType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;

use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

use Symfony\Component\Validator\Constraints as Assert;

class EntryTypeExtension extends AbstractTypeExtension
{
	/**
     * @var EccubeConfig
     */
    protected $eccubeConfig;
	
	/**
     * @var EntityManagerInterface
     */
    protected $entityManager;

    /**
     * EntryType constructor.
     *
     * @param EccubeConfig $eccubeConfig
     */
    public function __construct(EccubeConfig $eccubeConfig, EntityManagerInterface $entityManager)
    {
        $this->eccubeConfig = $eccubeConfig;
		$this->entityManager = $entityManager;
    }
	
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
		// 住所の重複チェック
		$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
            $form = $event->getForm();
            /** @var Customer $Customer */
            $Customer = $event->getData();
			
			if( !empty($Customer->getPref()) && !empty($Customer->getAddr01()) && !empty($Customer->getAddr02()) ){
				// SQL作成
				$sql = "SELECT * ";
				$sql .= " FROM dtb_customer ";
				$sql .= " WHERE customer_status_id != 3 "; // 退会以外
				$sql .= " AND pref_id = :pref_id ";// 都道府県
				$sql .= " AND REPLACE( CONCAT(addr01,addr02), '‐', '-' ) collate utf8_unicode_ci = :addr ";// 住所(半角・全角区別しない)  全角ハイフンを半角に
				
				
				$stmt = $this->entityManager->getConnection()->prepare($sql);
				
				$stmt->bindValue('pref_id', $Customer->getPref()->getId());
				
				$addr = $Customer->getAddr01().$Customer->getAddr02();
				$addr = str_replace('‐', '-', $addr);// 全角ハイフンを半角に
				
				$stmt->bindValue('addr', $addr);
				
				$stmt->execute();
				$results = $stmt->fetchAll();
				
				if( !empty($results) ){
					$form['address']['pref']->addError(new FormError(""));
					$form['address']['addr01']->addError(new FormError(""));
					$form['address']['addr02']->addError(new FormError("登録済みの住所です"));
				}
			}
			
        });
		
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return EntryType::class;
    }
    
    /**
     * {@inheritdoc}
     */
    public static function getExtendedTypes(): iterable
    {
        yield EntryType::class;
    }
}
// キャッシュ削除
php bin/console cache:clear --no-warmup