スタッフブログ


WooCommerceの会員登録ページに入力欄を追加したい!

WooCommerceの会員登録ページに入力欄を追加したい!

ショッピングサイトを作らせれば、右に出るものは……ごまんといる、、、ウェブクリエイター中井です。

WordPressを利用したショッピングサイトを制作する際に、便利なプラグインはたくさんありますが、
今回はWooCommerceというプラグインについて書いていきます。

高機能なショッピングサイト作成用プラグインWooCommerce

WooCommerceはWordPressにショッピング機能を導入できるプラグインです。

 

商品の登録・管理、カテゴリー分け、カラーやサイズなどのオリジナルバリエーションの設定や
提携サービスが豊富だったり、管理画面で商品ごとの購買数や売り上げがわかりやすく確認できたりと、紹介しきれないくらい様々な機能があります。

 

こんなに機能満載なんだからもうみんな使ってるよね!…と言いたいところですが、
高機能すぎるためにとっつきにくいところがあるのも確かで、WordPressをガンガンカスタマイズしてる中上級者向きなプラグインとも言えます。

 

なにより、外国製なのもあって日本のユーザーには慣れない設計なところも。

 

例えば会員登録画面。

メールアドレスとパスワードの入力フォームのみのページ

 

プラグインを入れて、そのまま使おうと思うと

【商品購入時に任意で同時会員登録】する

 

 

あるいは、設定を変更したとしても

【メールアドレスとパスワードの入力フォームのみのページ】が表示される

 

 

といったシンプルなつくりです。

 

正直言うと、オンラインショップ慣れしてる人からしたらけっこう楽なつくりだと思ってます。
前者だと購入の過程で入力したものがそのまま会員情報として登録されますし、
後者であっても、入力するのはメールアドレスとパスワードだけで、非常にスムーズです。

 

それでもやっぱり…会員登録ページはしっかり存在して
そこに、住所や電話番号を入力させたくなるのが、人の性というものでしょう…笑

会員登録ページに項目追加する場合の前提条件

以降は下のような前提で説明させてもらいます。

 

前提1)下記のプラグインがWordPressにインストールされている

 

  • WooCommerce
  • WooCommerce for Japan

 

 

前提2)WordPressのテーマファイルをカスタマイズできる環境にある

 

  • HTML、CSS、PHP、WordPressなどに触れたことがある
  • テーマファイル内のfunction.phpを編集できる
  • 開発・テスト用の環境が確保できている

 

 

それではいってみましょう~。

会員登録ページに項目を追加しよう!

項目を追加するのは、多少Web制作に精通していて、
WordPressに慣れている人であれば簡単にできる方法もあります。

 

 

WooCommerceのプラグインフォルダの中にはtemplateというフォルダが存在していて、
テーマフォルダの中にwoocommerceフォルダを作成後、そのtemplatesフォルダ内の編集したいファイルを移して書き換えればいいんです。

 

会員登録ページであればこちらが該当ファイルです。
templates > myaccount > form-login.php

 

この場合だと直にHTMLやPHPを入力していけば理想通りにすることも可能ですし、
WooCommerceのアップデートにも影響を受けません。

 

 

それじゃあ、この方法で万事解決だね!…ともいかず、この方法にももちろんデメリットがあって、
WooCommerceのアップデートの影響を受けない=アップデートされないということは、
もし仮に、セキュリティ上必要なアップデートがあってもその恩恵を受けられないことにもなります。

 

一応、管理画面でシステム状況を確認できるページがWooCommerce側で用意されていて、
テーマ内の古いテンプレートファイルには警告が表示されるようになってるので、

こまめに見て都度調整をすることもできますが、限度もありますよね。

function.phpに追記!追記!

幸いにもWooCommerceのテンプレートファイルにはいたるところにフックが仕込まれていて、
テーマファイル側からカスタマイズしやすいつくりになってます。

 

主には下記のフックを活用します。
【フォームの表示部分】
woocommerce_register_form_start
【登録時】
woocommerce_register_post
【会員制作時】
woocommerce_created_customer

 

 

 

今回は、このように書いてみました。


<?php
/*=====================================

フォーム作成用配列

======================================*/
$register_form_arr = array(
	array( 'layout' => 'first', 'label' => '姓', 'ex' => '', 'name' => 'billing_last_name', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'last', 'label' => '名', 'ex' => '', 'name' => 'billing_first_name', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'first', 'label' => '姓(ヨミガナ)', 'ex' => '', 'name' => 'billing_yomigana_last_name', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'last', 'label' => '名(ヨミガナ)', 'ex' => '', 'name' => 'billing_yomigana_first_name', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'first', 'label' => '郵便番号', 'ex' => '(例:123-4567)', 'name' => 'billing_postcode', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'last', 'label' => '都道府県', 'ex' => '', 'name' => 'billing_state', 'req' => true, 'type' => 'select', 'err' => '未選択' ),
	array( 'layout' => 'wide', 'label' => '市区町村', 'ex' => '', 'name' => 'billing_city', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'wide', 'label' => '住所詳細', 'ex' => '', 'name' => 'billing_address_1', 'req' => true, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'wide', 'label' => '', 'ex' => '', 'name' => 'billing_address_2', 'req' => false, 'type' => 'text', 'err' => '' ),
	array( 'layout' => 'first', 'label' => '電話番号', 'ex' => '', 'name' => 'billing_phone', 'req' => true, 'type' => 'text', 'err' => '' )
);

/*=====================================

会員登録ページに入力フォーム追加

======================================*/
add_action( 'woocommerce_register_form_start', 'cs_wc_extra_register_fields' );

function cs_wc_extra_register_fields() {

	global $register_form_arr;
	$country_code = 'JP';
	$states = WC()->countries->get_states( $country_code );
	?>

	<input type="hidden" name="billing_country" id="billing_country" value="JP"  class="country_to_state" />

	<?php foreach( $register_form_arr as $item ): ?>

	<p class="form-row form-row-<?php echo $item['layout'] ?> <?php if( $item['req'] ) echo 'validate-required' ?>">
		<?php if( $item['label'] ): ?>
		<label for="reg_<?php echo $item['name'] ?>"><?php echo $item['label'].$item['ex'] ?> <?php if( $item['req'] ) echo '<span class="required">*</span>' ?></label>
		<?php endif; ?>

		<?php if( $item['type'] == 'text' ): ?>

		<input type="text" class="input-text" name="<?php echo $item['name'] ?>" id="reg_<?php echo $item['name'] ?>" value="<?php if ( ! empty( $_POST[ $item['name'] ] ) ) esc_attr_e( $_POST[ $item['name'] ] ); ?>" />

	<?php elseif( $item['type'] == 'select' ): ?>

		<select name="<?php echo $item['name'] ?>" id="reg_<?php echo $item['name'] ?>" class="state_select " data-placeholder="">
			<option value="">選択してください…</option>
		<?php
			foreach ( $states as $state_code => $state_name ) {
				echo '<option value="' . esc_attr( $state_code ) . '" ' . selected( ( $_POST['billing_state'] == $state_code ), true, false ) . '>' . esc_html( '     ' . $state_name ) . '</option>';
			}
		?>
		</select>

	<?php endif; ?>

	</p>

	<?php
	endforeach;

}

/*=====================================

必須項目が未入力の場合のエラーメッセージ表示

======================================*/
add_action( 'woocommerce_register_post', 'cs_wc_validate_extra_register_fields', 10, 3 );

function cs_wc_validate_extra_register_fields( $username, $email, $validation_errors ) {
	global $register_form_arr;

	$errors_temp = '';

	foreach( $register_form_arr as $item ) {
		if( $item['req'] ) {
			$post_item_name = $_POST[ $item['name'] ];
			if ( isset( $post_item_name ) && empty( $post_item_name ) ) {
				$err_mess = ( $item['err'] )? $item['err'] : '入力されていません' ;
				$validation_errors->add( $item['name'].'_error', $item['label'].'が'.$err_mess );
			} else {
				if( in_array( $item['name'], array( 'billing_yomigana_last_name', 'billing_yomigana_first_name' ) ) ) {
					if( ! preg_match( "/^[ァ-ヾ]+$/u", $post_item_name ) ) {
						$validation_errors->add( $item['name'].'_error', $item['label'].'はすべて全角カタカナで入力してください' );
					}
				}
			}
		}
	}

}

/*=====================================

入力項目をユーザー情報に登録

======================================*/
add_action( 'woocommerce_created_customer', 'cs_wc_save_extra_register_fields' );

function cs_wc_save_extra_register_fields( $customer_id ) {
	global $register_form_arr;

	if ( isset( $_POST['billing_country'] ) ) {
		update_user_meta( $customer_id, 'billing_country', sanitize_text_field( $_POST['billing_country'] ) );
	}

	if ( isset( $_POST['billing_first_name'] ) ) {
		update_user_meta( $customer_id, 'first_name', sanitize_text_field( $_POST['billing_first_name'] ) );
	}

	if ( isset( $_POST['billing_last_name'] ) ) {
		update_user_meta( $customer_id, 'last_name', sanitize_text_field( $_POST['billing_last_name'] ) );
	}

	if( isset( $_POST['billing_first_name'] ) || isset( $_POST['billing_last_name'] ) ) {
		update_user_meta( $customer_id, 'display_name', sanitize_text_field( $_POST['billing_last_name'] ).' '.sanitize_text_field( $_POST['billing_first_name'] ) );
		update_user_meta( $customer_id, 'nickname', sanitize_text_field( $_POST['billing_last_name'] ).' '.sanitize_text_field( $_POST['billing_first_name'] ) );
	}

	foreach( $register_form_arr as $item ) {

		$post_item_name = $_POST[ $item['name'] ];

		if( in_array( $item['name'], array( 'billing_yomigana_last_name', 'billing_yomigana_first_name' ) ) ) {
			$post_item_name = mb_convert_kana( $post_item_name, 'C' );
			$post_item_name = mb_convert_kana( $post_item_name, 'K' );
		} elseif( $item['name'] == 'billing_postcode' ) {
			$post_item_name = add_hyphen_to_the_postal_code( $post_item_name );
		}
		update_user_meta( $customer_id, $item['name'], sanitize_text_field( $post_item_name ) );
	}

	$post_shipping_postcode = $_POST['shipping_postcode'];
	update_user_meta( $customer_id, 'shipping_postcode', sanitize_text_field( $post_shipping_postcode ) );

}

?>

表示結果!

こんな表示に!

入力してほしい情報を追加することができました

まとめ

実際はログインフォームも一緒に表示されるので、表示を切り替えたりする工夫も必要です。

上記コードはどんな環境でもうまく動くとは限らないので、利用する場合は十分テストが必要かと思います。
今回のようなカスタマイズをしなくても、WooCommerceのファイル内容を眺めているだけでもけっこう勉強になったりします。
すごいなぁ、WooCommerce。