今日のウェブアプリケーションには、インテリジェンスと位置情報への対応機能が求められます。例えば、ECサイトでは海外発送料金の計算、ニュースサイトでは地域に特化した情報の配信が必要です。位置情報を利用することで、静的なWordPressサイトでの体験を動的でパーソナライズなものに変えることができます。しかし適切なサーバーなしでは、この機能の導入は複雑なものになります。

今回は、WordPressにジオロケーション機能を導入する方法をご紹介していきます。ご紹介する手順では、サイトへの導入に伴う課題を解消するKinstaの内蔵機能を使用します。

ジオロケーションとジオターゲティング

位置情報を使ったアプリケーションは、ジオロケーション(位置情報の取得)とジオターゲティング(位置情報を活用したターゲティング)という2つの重要な技術を中心に構成されています。WordPressの文脈においては、それぞれ異なる目的を果たします。

  • ジオロケーション─訪問者の位置を特定
  • ジオターゲティング─ジオロケーションのデータに基づいて特定のコンテンツや体験を提供

Netflixが良い例として挙げられます。たとえば海外旅行先などでNetflixにアクセスすると、ジオロケーションを通じて現在地を特定し、地域のライセンス契約に一致するようにジオターゲティングを通じてコンテンツライブラリが調整されるのは見たことがあるかもしれません。同社はジオロケーションとジオターゲティングの併用することで、国際的なメディア権利のコンプライアンスを維持しながら、シームレスな体験を構築しています。

Netflixのウェブサイト
Netflixのウェブサイト

訪問者の位置情報を検出する方法は主に2種類あります。

  • IPベース:IPアドレスを地理的地域にマッピングするデータベースに依存し、ユーザーの許可を得る必要がない。Kinstaの組み込み機能を含め、ほとんどのサーバーサイドのジオロケーションソリューションはIPベースで位置情報を検出している。
  • GPSベース:ブラウザのAPIを通じてデバイスの位置情報ハードウェアにアクセス。より正確な座標が提供されるが、ユーザーの明示的な同意が必要。Googleなどで検索すると位置情報に基づいて近くの店舗やサービスが表示される機能や天気予報アプリで使われている。

ジオロケーションとジオターゲティングは連携して機能しますが、前者には用途に応じてさまざまな技術が存在します。どちらが優れているというわけではなく、それぞれに特有の利点があり、状況に応じて適切に活用することが重要です。

ジオロケーションの用途

ウェブサイトにジオロケーション機能を導入するは、ビジネスとユーザーの双方に利点があります。例えば、パーソナライゼーションはエンゲージメントを促進します。個々のユーザーにパーソナライズされた体験を提供できれば、より多くのユーザーがサービスを利用してくれる可能性が高まります。

Amazonでは、アクセスしている場所に応じて各商品の配送予定日が表示されます。

Amazonの商品ページでは位置情報に基づいて配送予定日時が表示される
Amazonの商品ページでは位置情報に基づいて配送予定日時が表示される

また、Amazonプライムで配信されるイベントの日時も国や地域に応じて適切に表示されます。

プロ野球の試合の現地時間が表示されているAmazon.com
プロ野球の試合の現地時間が表示されているAmazon.com

例えば、天気予報サイトにアクセスすると、自動的に自分のいる地域の予報が表示されます。どのような実装であっても、パーソナライゼーションはユーザー体験の摩擦を減らし、コンバージョン率の大幅な向上に貢献してくれます。

法規制の遵守には、位置情報の認識も重要です。例えば、ヨーロッパのGDPR(一般データ保護規則)や米国カリフォルニア州のCCPA(消費者プライバシー法)など、多くの地域でユーザーデータの取り扱いに関する特定の要件が義務付けられています。適切なジオロケーション機能の導入によって、訪問者ごとにこれらの要件を満たすことができます。

また、コンテンツのローカライゼーションも信頼性を高めます。価格が現地通貨で表示され、地域に応じた配送情報が提示されると商品の購入率が高くなることが実証されており、Common Sense Advisoryの調査によると、消費者の4分の3が母国語で商品を購入することを好んでいます。

WordPressにジオロケーション機能を追加する方法

WordPressの柔軟なアーキテクチャにより、サイトに位置情報機能を追加する方法は複数存在し、使用するサーバー、プラグインの利用、コーディングの知識など、さまざまな要素が適切なアプローチの選択に影響します。ただし、実際にデータを扱う方法はいくつかに分かれます。

WordPressで位置情報を利用する

WordPressのコアには多くの基本機能が組み込まれていますが、ジオロケーション機能は含まれていません。しかし、いくつかの方法で位置情報の保存と処理をサポートしています。

WordPressデータベース

例えば、WordPressのデータベースは、カスタムフィールドや専用の位置情報テーブルを使用して、座標や位置情報を保存することができます。

また、位置情報ベースのタクソノミーを扱うことも可能で、これは独自の位置情報データベースを運用する店舗検索や不動産サイトに適しています。デフォルトでは、WordPressが位置情報を保存することはありません。

WordPress REST API

WordPressのREST APIもジオロケーションデータの処理をサポートしていますが、専用のエンドポイントはありません。外部サービスやモバイルアプリと通信する位置情報対応のアプリケーションを構築するには、以下のように独自のエンドポイントを作成する必要があります。

add_action('rest_api_init', function() {
    // ジオロケーションエンドポイント用のカスタム名前空間を作成
register_rest_route('your-site-geo/v1', '/location', [
        'methods' => 'GET',
        'callback' => 'handle_location_request',
        'permission_callback' => function() {
            return true;
        }
    ]);
});

function handle_location_request($request) {
    // ジオロケーションデータへのアクセス(Kinstaの実装を使用した例)
    $location = [
        'country' => $_SERVER['GEOIP_COUNTRY_CODE'] ?? null,
        'city' => $_SERVER['GEOIP_CITY'] ?? null,
        'latitude' => $_SERVER['GEOIP_LATITUDE'] ?? null,
        'longitude' => $_SERVER['GEOIP_LONGITUDE'] ?? null
    ];
    
    return new WP_REST_Response($location, 200);
}

これにより、/wp-json/your-site-geo/v1/location に新たなエンドポイントが作成され、あらゆるAPI利用者(APIコンシューマー)に対して位置情報データを返すようになります。

上のコードでは、your-site-geoをカスタム名前空間として使用しています。他のプラグインやカスタムコードとの競合を防ぐため、名前空間は要件に適したものにしてください。以下のWordPressの名前空間ガイドラインに従うのが最善です。

  • 競合を避けるためにベンダーやパッケージ固有の接頭辞を使用する
  • バージョン番号(v1など)を含める
  • 明確かつ目的に特化したものにする

既存のエンドポイントの位置情報を登録することもできます。

add_action('rest_api_init', function() {
    register_rest_field('post', 'location_data', [
        'get_callback' => function($post) {
            return get_post_meta($post['id'], 'location_data', true);
        },
        'update_callback' => function($value, $post) {
            update_post_meta($post->ID, 'location_data', $value);
        },
        'schema' => [
            'type' => 'object',
            'properties' => [
                'latitude' => ['type' => 'number'],
                'longitude' => ['type' => 'number'],
                'country' => ['type' => 'string'],
                'city' => ['type' => 'string']
            ]
        ]
    ]);
});

多くの場合、ジオロケーション機能を構築するためには、まずREST APIを利用します。

カスタム投稿タイプ

WordPressでカスタム投稿タイプを使用している場合は、新規作成するコンテンツタイプに位置情報のメタデータを含めることができます。これにより、複雑なデータベースの変更を行うことなく、位置情報を使ってコンテンツを整理することが可能です。

まずは、WordPressに投稿タイプを登録します。

register_post_type('store_location', [
    'public' => true,
    'label' => '店舗情報',
    'supports' => [
        'title',
        'editor',
        'Custom-fields'  // カスタムフィールドとメタを有効化
    ]
]);

収集した座標を保存するためのカスタムメタボックスを作成し、このためのHTMLを生成します。

<?php
add_action('add_meta_boxes', function() {
    add_meta_box(
        'store_location_coordinates',
        'Store Coordinates',
        'render_location_meta_box',
        'Store_location'  // このメタボックスを表示する投稿タイプ
    );
});

function render_location_meta_box($post) {
    // 既存の座標があれば取得
    $latitude = get_post_meta($post->ID, 'latitude', true);
    $longitude = get_post_meta($post->ID, 'longitude', true);    

    // フォームフィールドを出力
    ?>
    <label>Latitude:
        <input type="number" 
               step="any" 
               name="latitude" 
               value="<?php echo esc_attr($latitude); ?>">
    </label>
    <label>Longitude:
        <input type="number" 
               step="any" 
               name="longitude" 
               value="<?php echo esc_attr($longitude); ?>">
    </label>
    <?php
}

WordPressサイトで投稿を公開または保存するごとに、位置情報を保存することが重要です。

add_action('save_post_store_location', function($post_id) {
    // オートセーブかどうかを確認
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }    

    // 緯度があれば保存
    if (isset($_POST['latitude'])) {
        update_post_meta(
            $post_id,
            'latitude',
            sanitize_text_field($_POST['latitude'])
        );
    }    

    // 経度があれば保存
    if (isset($_POST['longitude'])) {
        update_post_meta(
            $post_id,
            'longitude',
            sanitize_text_field($_POST['longitude'])
        );
    }
});

近くにある場所を取得する関数を作るには、さまざまな方法があります。以下は、(理論上)場所の緯度と経度を取得する関数の簡単な例です。

function get_nearby_locations($lat, $lng, $radius = 10) {
    $locations = get_posts([
        'post_type' => 'store_location',
        'posts_per_page' => -1
    ]);

    $nearby = array_filter($locations, function($location) use ($lat, $lng, $radius) {
        $store_lat = get_post_meta($location->ID, 'latitude', true);
        $store_lng = get_post_meta($location->ID, 'longitude', true);

        return calculate_distance($lat, $lng, $store_lat, $store_lng) <= $radius;
    });

    return $nearby;
}

どれを使用するかは、特定の要件に依存します。例えば、単純な位置情報のメタデータにはカスタムフィールドを使うか、ヘッドレス実装のためにREST APIを拡張します。位置情報が重要になるコンテンツには、おそらくカスタム投稿タイプが適切でしょう。

プラグインを使ったジオロケーション機能の導入

WordPressプラグインは多数存在し、サイトで位置情報を使用するためのプラグインも数多く見つかります。例えば、If-So Geolocationや Geolocation IP Detectionは、ユーザー評価の高く、サポートも充実しており、定期的に更新も行われているおすすめの選択肢です。

Geolocation IP Detectionプラグイン
Geolocation IP Detectionプラグイン

いずれもシンプルで多機能なプラグインで、ユーザーフレンドリーです。以下のような利点があります。

  • 迅速なデプロイと導入が可能でカスタムコード不要
  • プラグイン開発者の対応(更新を含め)により、ユーザーサイドでのメンテナンスが不要
  • 必要に応じてコミュニティによるサポートやドキュメントを利用可能

特定の種類の開発においては、プラグインの品質に依存することになるため、プラグインの使用がベストな選択肢ではない可能性があります。また、独自のWordPress製品を提供している場合、外部のプラグインと提携するのは適切でないかもしれません。さらに、プラグインごとに独自の位置情報データベースを実装しているため、その品質も他の機能と同様にバラつきがあります。

既存のサイトに位置情報を追加したいサイト所有者やエンドユーザーにとっては優れた方法ですが、他のプラグインとの競合、サーバーへの過負荷、カスタム実装の限界などの懸念から、より堅牢な方法が求められる場合があります。

WordPressにおけるジオロケーション機能の応用例

WordPressのコードベースでジオロケーションを使用する例として、WooCommerceでは税金の計算や配送ルールの設定にジオロケーション機能が使用されています。

WooCommerceのジオロケーション機能
WooCommerceのジオロケーション機能

MaxMindのGeoIP2データベースを使用して買い物客の所在地を自動検出し、最初にアクセスするページから正確な価格と配送オプションを提供することができます。

他のプラグインでもジオロケーションがサポートされており、Gravity FormsのGravity Geolocation拡張機能がその一例です。Gravity Formsが座標やその他の関連データを割り当てます。

特定の用途に位置認識の必要性を適応させる柔軟性があり、特にリードジェネレーションやサービス申請のフォームに有用です。

Kinstaの組み込みのジオロケーション機能

Kinstaのお客様は、コントロールパネルのMyKinstaからWordPressにジオロケーション機能を簡単に組み込むことができます。

Kinstaのジオロケーションシステム

Kinstaのジオロケーション機能は、以下2つの強力な技術を利用しています。

  • Nginxのジオロケーションモジュール─サーバーレベルの位置情報を効率的に取得
  • MaxMindのGeoIP2データベース─正確で最新のロケーションマッピングを行う

この組み合わせは、プラグインやコードベースのソリューションと比較して以下のような利点があります。

  • 位置情報の検出はサーバーレベルで行われるため、パフォーマンスへの影響が最小限
  • 機能の定期的なメンテナンスにより、常に最新の位置情報を取得できる
  • JavaScriptやブラウザのパーミッションが不要なため、信頼性の高い位置情報の認識と検出を提供
  • Kinstaのエッジキャッシュとの統合可能

KinstaのIPジオロケーション機能は、位置情報を公開し、それをシステム全体(スタック)に渡すことで、高性能かつ柔軟に適応できる優れた機能を提供します。

利用可能な位置情報

WordPressはPHPを使用し、KinstaのIPジオロケーション機能は、PHP変数$_SERVERに位置情報中心の情報を渡します。

さまざまなエンドポイントと変数が用意されており、それぞれ異なるデータセットを返します。

// 基本的な地理的情報

$country_code = $_SERVER['GEOIP_COUNTRY_CODE']; // 2文字の国コード(「JP」や「US」など)
$country_name = $_SERVER['GEOIP_COUNTRY_NAME']; // 正式国名
$region = $_SERVER['GEOIP_REGION'];             // 都道府県コード
$city = $_SERVER['GEOIP_CITY'];                 // 都市名
$postal_code = $_SERVER['GEOIP_POSTAL_CODE'];   // 郵便番号

// 正確な位置情報
$latitude = $_SERVER['GEOIP_LATITUDE'];         // 十進緯度
$longitude = $_SERVER['GEOIP_LONGITUDE'];       // 十進経度

さまざまな国や都市のコードフォーマットなど、使用できる変数は他にもあります。いずれにしても、公開されたすべての変数は、KinstaのIPジオロケーション機能に基づいてカスタムPHPをコーディングする方法を提供します。

MyKinstaでジオロケーション機能を導入する

MyKinstaの多くの機能と同様に、ジオロケーション機能の実装は簡単に行うことができます。MyKinstaにログイン後、「WordPressサイト」>(サイト名)>「ツール」画面に移動します。

MyKinstaの「ツール」画面
MyKinstaの「ツール」画面

ジオロケーション」セクションの「利用する」をクリックし、モーダルウィンドウで国単位または国とと都市単位で適用するかを選択します。

ジオロケーションの設定
ジオロケーションの設定

エッジキャッシュを使用している場合、警告が表示されることがあります。これは、国境付近などの「狭い範囲」のジオロケーションキャッシュのバリエーションをサポートされていないためです。その代わりに、キャッシュはページへの最初の訪問者がどこからアクセスしているのかに基づいて、それぞれのPoP(Point of Presence)ロケーションに保存されます。

ジオロケーション設定を選択し、「利用する」をクリックするだけで完了です。その後、「ジオロケーション」セクションは以下のようになります。

ジオロケーション機能が有効化された状態
ジオロケーション機能が有効化された状態

ジオロケーションを無効にするには、3つの点を選択して、「無効化する」をクリックしてください。また、位置情報に基づいてサイトへのアクセスを制限したい場合は、MyKinstaのサポートチャットよりご連絡ください。

位置情報アプリケーションの構築

NginxとMyKinstaのジオロケーション機能により、コードスニペットとKinstaの組み込み機能を活用して、要件に応じたソリューションをセットアップすることができます。

コーディングなしのソリューションの場合は、MyKinstaのリダイレクト機能を使用するのが理想的です。

位置情報ベースのリダイレクト

KinstaのIPジオロケーションの特筆すべき機能の1つとして、高度なトラフィックのルーティングを通じて位置情報ベースの条件を適用できます。

これをコーディングで行うと、以下のように複雑な作業になります。

class GeographicRedirects {
    public function __construct() {
        add_action('template_redirect', [$this, 'handle_redirects']);
    }

    public function handle_redirects() {
        $country_code = $_SERVER['GEOIP_COUNTRY_CODE'] ?? null;

        if ($country_code) {
            $redirect_url = $this->get_redirect_url($country_code);
            if ($redirect_url) {
                wp_redirect($redirect_url, 301);
                exit;
            }
        }
    }
    
    private function get_redirect_url($country_code) {
        $redirects = [
            'DE' => 'https://de.example.com',
            'FR' => 'https://fr.example.com',
            'ES' => 'https://es.example.com'
        ];

        return $redirects[$country_code] ?? null;
    }
}

new GeographicRedirects();

MyKinstaでは、国と都市を選択して(ジオロケーション機能を利用している場合)リダイレクトルールを簡単に設定できます。

MyKinstaでリダイレクトルールを設定
MyKinstaでリダイレクトルールを設定

このように、Kinstaではリダイレクトルールとともにジオロケーション機能を使用できます。リダイレクト元とリダイレクト先のURLを入力し、ドメイン、国と都市を選択して、ステータスコードを選択するだけでOKです。「リダイレクトルールを追加」をクリックすると、Nginxの設定に適用されます。

インタラクティブな地図の統合

動的な店舗検索ツールは、訪問者がアクセスする地域の近くの店舗を表示するものです。広範囲に多数の店舗を構えている場合に特に有用になります。

IKEAの店舗検索ページ
IKEAの店舗検索ページ

KinstaのIPジオロケーション変数とGoogle Maps APIを使用することで、上記のようなインタラクティブなページを作成することができます。これには、Google Maps APIキーGoogle Maps JavaScript APIの基礎知識と全店舗の位置情報が必要です。後者はカスタム投稿タイプやデータベースから取得することができます。

実装方法はテーマのfunctions.phpファイルまたはカスタムプラグインにコードを追加するのが一般的です。Google Maps APIキーを設定したら、店舗の位置情報構造を設定します。

// 店舗の位置情報投稿タイプの登録
add_action('init', function() {
    register_post_type('store_location', [
        'public' => true,
        'label' => '店舗情報',
        'supports' => ['title', 'editor', 'custom-fields'],
        'show_in_rest' => true
    ]);

    // 位置情報用カスタムフィールドの登録
    register_meta('post', 'latitude', [
        'type' => 'number',
        'single' => true,
        'show_in_rest' => true
    ]);
    register_meta('post', 'longitude', [
        'type' => 'number',
        'single' => true,
        'show_in_rest' => true
    ]);
});

店舗の位置情報をインポートするには、WordPress管理画面のインターフェースを使用するか、カスタム投稿タイプを作成するか、カスタムフィールドに緯度と経度を追加するか、コンテンツに店舗情報を追加するか、あるいは自動インポートを実行します。例えば、以下のようになります。

function import_store_locations($stores) {
    foreach ($stores as $store) {
        $post_id = wp_insert_post([
            'post_type' => 'store_location',
            'post_title' => sanitize_text_field($store['name']),
            'post_status' => 'publish'
        ]);

        if (!is_wp_error($post_id)) {
            update_post_meta($post_id, 'latitude', floatval($store['lat']));
            update_post_meta($post_id, 'longitude', floatval($store['lng']));
            update_post_meta($post_id, 'address', sanitize_text_field($store['address']));
            update_post_meta($post_id, 'phone', sanitize_text_field($store['phone']));
        }
    }
}


// 使用例:
$stores = [
    [
        'name' => '新宿本店',
        'lat' => 35.6895,
        'lng' => -139.6917,
        'address' => '東京都新宿区西新宿1-1-1',
        'phone' => '03-1234-5678'
    ]
    // さらに店舗を追加...
];

import_store_locations($stores);

店舗検索ツールを実装するには、数行のコーディングとKinstaの変数が必要になります。

class StoreLocator {
    private $visitor_location;
    private $google_maps_key;
 
    public function __construct($google_maps_key) {
        $this->google_maps_key = $google_maps_key;
        $this->visitor_location = $this->get_visitor_location();        

        add_action('wp_enqueue_scripts', [$this, 'enqueue_maps_scripts']);
    }

    private function get_visitor_location() {
        // Kinstaのジオロケーションデータを使用
        if (isset($_SERVER['GEOIP_LATITUDE'], $_SERVER['GEOIP_LONGITUDE'])) {
            return [
                'lat' => floatval($_SERVER['GEOIP_LATITUDE']),
                'lng' => floatval($_SERVER['GEOIP_LONGITUDE'])
            ];
        }

        // 国の中心地点にフォールバック
        if (isset($_SERVER['GEOIP_COUNTRY_CODE'])) {
            return $this->get_country_center($_SERVER['GEOIP_COUNTRY_CODE']);
        }

        // 新宿をデフォルトに設定
        return ['lat' => 35.6895, 'lng' => -139.6917];
    }

    private function get_nearby_stores($radius = 50) {
        return get_posts([
            'post_type' => 'store_location',
            'posts_per_page' => 10,
            'meta_query' => [
                [
                    'key' => 'latitude',
                    'value' => [
                        $this->visitor_location['lat'] - ($radius / 111),
                        $this->visitor_location['lat'] + ($radius / 111)
                    ],
                    'type' => 'NUMERIC',
                    'compare' => 'BETWEEN'
                ]
            ]
        ]);
    }
…

ここから、$store_locator->render_map()を使用して地図をテンプレートに追加することができます。

動的なコンテンツ提供

位置情報固有のコンテンツ、価格設定、宣伝内容は、ジオロケーションに依存します。位置情報を考慮したコンテンツ配信により、訪問者の位置に基づいてサイトのコンテンツ、価格、宣伝内容をカスタマイズすることができます。

これには、ターゲットとする地域ごとにコンテンツを用意する必要があります。その後、位置情報データを処理し、キャッシュキーを生成します。これにより、位置情報を利用しながら効率的なコンテンツ配信が可能になります。

private function get_location_context() {
    // 位置情報に基づいて一意のキャッシュキーを作成
    $context = [
        'country' => $_SERVER['GEOIP_COUNTRY_CODE'] ?? null,
        'region'  => $_SERVER['GEOIP_REGION'] ?? null,
        'locale'  => get_locale()
    ];

    // 必要に応じて通貨とタイムゾーンのデータを追加
    if ($this->requires_currency_handling) {
        $context['currency'] = $this->get_country_currency($context['country']);
    }

    return $context;
}

これが位置情報ベースの意思決定とコンテンツ処理システムの基盤になり、地域に応じた価格設定とコンテンツの両方を処理することができます。

private function process_dynamic_content($content, $context) {
    // 通貨換算による価格設定
    if (strpos($content, '{price:') !== false) {
        $content = preg_replace_callback(
            '/{price:([0-9]+.?[0-9]*)}/',
            fn($matches) => $this->format_price(
                floatval($matches[1]), 
                $context['currency']
            ),
            $content
        );
    }

    // 地域コンテンツブロックの処理
    if (strpos($content, '[region:') !== false) {
        $content = preg_replace_callback(
            '/[region:([^]]+)](.*?)[/region]/s',
            function($matches) use ($context) {
                $regions = array_map('trim', explode(',', $matches[1]));
                return in_array($context['country'], $regions) ? $matches[2] : '';
            },
            $content
        );
    }

    return $content;
}

これにより、訪問者の所在地に自動的に適用する以下のようなシンプルなマーカー(プレースホルダー)をコンテンツに使用できます。

[region:JP]
    <p>{price:5000}円以上の購入で送料無料!</p>
[/region]
[region:US,GB,DE,FR]
    <p>{price:10000}円以上の購入で送料無料!</p>
[/region]

シンプルな実装は、パフォーマンスの最適化にも役立ちます。これは見落とされがちですが、効率的なキャッシュは、位置情報を認識するコンテンツのパフォーマンス維持につながります。Kinstaのキャッシュ機能はこの作業に適しています。

フォームの事前入力と検証

位置情報を考慮したフォームでは、地域によって異なる住所形式、郵便番号、電話番号を処理しなければなりません。そのため、これらの異なる地域に合わせたバリデーション(検証)およびフォーマットのルールを定義することが重要です。

private $format_patterns = [
    'US' => [
        'postal' => [
            'pattern' => '^(?=.{5,10}$)d{5}(-d{4})?$',
            'transform' => fn($value) => strtoupper(trim($value))
        ],
        'phone' => [
            'pattern' => '^+1[2-9]d{2}[2-9]d{2}d{4}$',
            'transform' => fn($value) => '+1' . preg_replace('/D/', '', $value)
        ]
    ],
    'GB' => [
        'postal' => [
            'pattern' => '^(?=.{6,8}$)[A-Z]{1,2}[0-9][A-Z0-9]? ?[0-9][A-Z]{2}$',
            'transform' => fn($value) => preg_replace(
                '/^(.+?)([0-9][A-Z]{2})$/', 
                '$1 $2', 
                strtoupper(trim($value))
            )
        ]
    ]
];

上記のパターンは、国によって異なる郵便番号や電話番号の一般的なバリエーションを扱いますが、国によって住所形式の要件は異なります。これには体系的なアプローチを使用できます。

private function get_address_format($country_code) {
$formats = [
'JP' => [
'required' => ['postal', 'prefecture', 'city', 'street'],
'order' => ['postal', 'prefecture', 'city', 'street', 'street2'],
'state_label' => '都道府県',
'state_type' => 'select'
],
'US' => [
'required' => ['street', 'city', 'state', 'postal'],
'order' => ['street', 'street2', 'city', 'state', 'postal'],
'state_label' => 'State',
'state_type' => 'select'
]
];
return $formats[$country_code] ?? $formats['JP'];
}

次にフィールドのバリデーションは、地域の書式要件を尊重したものを実装します。

private function validate_field($field, $value, $country_code) {
    if (!isset($this->format_patterns[$country_code][$field])) {
        return true;  // 特別な検証は不要
    }

    $pattern = $this->format_patterns[$country_code][$field]['pattern'];
    $transform = $this->format_patterns[$country_code][$field]['transform'];

    // 検証前に値を変換
    $value = $transform($value);

    return (bool)preg_match("/$pattern/", $value);
}

簡単なスニペットでまとめてみます。

// 郵便番号の検証
if (!$this->validate_field('postal', $_POST['postal_code'], 'JP')) {
    $errors[] = '郵便番号が無効な形式です';
}

この実装は、訪問者の所在地に自動的に適応し、住所形式の地域的な差異を処理して、所在地固有のフィールドに対して適切なバリデーションを提供し、異なる地域間でデータの整合性を維持します。

まとめ

Kinstaのインフラを通してWordPressにジオロケーション機能を取り込むことで、強力な位置情報対応アプリケーションを構築することができます。KinstaのIPジオロケーション機能は、堅牢かつユーザーフレンドリーで、パフォーマンスへの影響も最低限に抑えることができます。さらに、プライバシーを重視し、コンプライアンスに準拠しているため安心です。

Steve Bonisteel Kinsta

Kinstaのテクニカルエディター。救急車や消防車を追いかける記者としてキャリアをスタート。1990年代後半からインターネット関連の技術情報を担当している。