woocommerceの決済ページをカスタマイズ

# 概要
最近案件でWooCommerceをカスタマイズすることがあり
その際決済ページに入力できる項目を増やそうと思いました。
色々調べてみたのですが出てきたやり方の多くが
ショートコードの決済ページのカスタマイズ方法でした。
現在のブロックによる決済ページには対応していなかったので
探すのに手間取ったので記録として残します。

# ショートコードの決済ページのカスタマイズ
WooCommerceでは以下のショートコードで
決済ページを作成することができます。
```
[woocommerce_checkout]
```

それによって生成される決済ページは
## オーバーライド
```functions.php
//オーバーライド例
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

function custom_override_checkout_fields( $fields ) {
    $fields['order']['order_comments']['placeholder'] = 'プレイスホルダーを変える';
    return $fields;
}
```
によってオーバーライドできたり
## 削除
```functions.php
//削除例
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

function custom_override_checkout_fields( $fields ) {
    unset( $fields['order']['order_comments'] );
    return $fields;
}	
```
削除したりできます。
また項目を追加することもできます。
## 追加
```functions.php
//追加例
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

function custom_override_checkout_fields( $fields ) {
     $fields['shipping']['shipping_phone'] = array(
        'label'       => __( 'Phone', 'woocommerce' ),
        'placeholder' => _x( 'Phone', 'placeholder', 'woocommerce' ),
        'required'    => false,
        'class'       => array( 'form-row-wide' ),
        'clear'       => true
     );

     return $fields;
}	
```
# ブロックの決済ページのカスタマイズ
ブロックの場合は以下のコードで削除、追加できます。
## 削除
```functions.php
add_filter(
	'woocommerce_get_country_locale',
	function ( $locale ) {
		$fields_to_hide = array(
			'state'      => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
			'city'       => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
			'postcode'   => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
			'first_name' => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
			'last_name'  => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
			'address_1'  => array(
				'hidden'   => 'true',
				'required' => 'false',
			),
		);

		foreach ( $locale as $country_code => $fields ) {
			$locale[ $country_code ] = wp_parse_args( $fields_to_hide, $fields );
		}

		return $locale;
	}
);
```
## 追加
```functions.php
add_action(
    'woocommerce_init',
    function() {
        // 日付フィールドの追加
        woocommerce_register_additional_checkout_field(
            array(
                'id'       => 'namespace/date',
                'label'    => '日付',
                'location' => 'order',
                'type'     => 'select',
                'options'  => [
                    [
                        'value' => '今日',
                        'label' => '今日'
                    ],
                    [
                        'value' => '明日',
                        'label' => '明日'
                    ],
                ]
            )
        );

        // 時間フィールドの追加
        woocommerce_register_additional_checkout_field(
            array(
                'id'       => 'namespace/time',
                'label'    => '時間',
                'location' => 'order',
                'type'     => 'select',
                'options'  => [
                    [
                        'value' => '9',
                        'label' => '9'
                    ],
                    [
                        'value' => '10',
                        'label' => '10'
                    ],
                    [
                        'value' => '11',
                        'label' => '11'
                    ],
                    [
                        'value' => '12',
                        'label' => '12'
                    ],
                    [
                        'value' => '13',
                        'label' => '13'
                    ],
                    [
                        'value' => '14',
                        'label' => '14'
                    ],
                    [
                        'value' => '15',
                        'label' => '15'
                    ],
                ]
            )
        );

        // 分フィールドの追加
        woocommerce_register_additional_checkout_field(
            array(
                'id'       => 'namespace/minutes',
                'label'    => '分',
                'location' => 'order',
                'type'     => 'select',
                'options'  => [
                    [
                        'value' => '00',
                        'label' => '00'
                    ],
                    [
                        'value' => '10',
                        'label' => '10'
                    ],
                    [
                        'value' => '20',
                        'label' => '20'
                    ],
                    [
                        'value' => '30',
                        'label' => '30'
                    ],
                    [
                        'value' => '40',
                        'label' => '40'
                    ],
                    [
                        'value' => '50',
                        'label' => '50'
                    ],
                ]
            )
        );
    }
);

// バリデーションの追加
add_action(
    'woocommerce_blocks_validate_location_order_fields',
    function ( \WP_Error $errors, $fields, $group ) {
        $date_value = isset($fields['namespace/date']) ? $fields['namespace/date'] : '';
        $time_value = isset($fields['namespace/time']) ? $fields['namespace/time'] : '';
        $minutes_value = isset($fields['namespace/minutes']) ? $fields['namespace/minutes'] : '';

        // どれか1つでも入力されている場合、残りの項目を空白にできないようにする
        if ($date_value || $time_value || $minutes_value) {
            if (empty($date_value)) {
                $errors->add('missing_date', '日付を選択してください。');
            }
            if (empty($time_value)) {
                $errors->add('missing_time', '時間を選択してください。');
            }
            if (empty($minutes_value)) {
                $errors->add('missing_minutes', '分を選択してください。');
            }
        }
    },
    10,
    3
);
```
追加に関しては今回バリデーションも設定しています。
更に詳しい情報は
[Additional Checkout Fields](https://developer.woocommerce.com/docs/cart-and-checkout-removing-checkout-fields/)
にあるのでぜひ読んでみてください！