プラグインなしのWordPress用お問い合わせフォーム

Seleccionar idioma
プラグインなしのWordPress用お問い合わせフォーム

ひとつ理解できないのは、WordPressにはまだシンプルで完全なコンタクトフォームがデフォルトで含まれていないことだ。

私は定期的にWordPressの最適化作業を行っているので、ここでもサードパーティのサイトでも、不必要に肥大化したプラグインや、使わないオプション、ブロック、装飾をコードで置き換えて負荷を軽くすることがよくある。

このコンタクトフォームは WordPress 用の完全でカスタマイズ可能なソリューションで、安全で使いやすく、ユーザーのプライバシーを尊重するように設計されています。また、オプションの追加や削除も自由自在です。これは私がここで使っているフォームです。

主な機能と特徴、そしてショートコードを使ってブログの任意のページや記事に追加する手順をご紹介します。

構造とオプション

1.フォームフィールド

  • 名前:ユーザー名を入力するための必須フィールド。
  • メールアドレスメールアドレスを入力する必須項目です。
  • メッセージ:ユーザーがメッセージを書くための必須フィールドです。15文字以上でなければなりません。
  • Sum captcha: 1から9までの2つの乱数の和を求めるシンプルなキャプチャ。
  • プライバシーポリシーの同意:フォームを送信する前に、プライバシーポリシーに同意するための必須チェックボックスです。

バリデーションとセキュリティ

  • 必須フィールドのバリデーション:すべてのフィールドは必須です。入力漏れがある場合はエラーメッセージが表示されます。
  • リンクの検証:名前フィールドやメッセージフィールドにリンク(URL)を使用することはできません。
  • Add Captcha:ユーザーに簡単な数学的操作を要求することで、自動スパムを防ぐ。
  • Google reCAPTCHA (オプション): Google reCAPTCHA キーが設定されている場合、ボットを防ぐために第二レベルのセキュリティが追加されます。reCAPTCHAキーがコードに追加されていない場合、コードはフォームに追加されません。
  • 例:パイナップル、ピザ、ビットコイン(カンマとスペースで区切る)。
  • Nonceセキュリティ:CSRF(クロスサイトリクエストフォージェリ)攻撃から保護します。

3.プライバシー

  • データ保存なし:ユーザーデータは保存されません(Eメール、IP、参照URL、何もありません)。このアプローチは、個人情報が収集または保存されないため、GDPRなどのプライバシー規制に準拠しています。
  • プライバシーポリシー:ユーザーがフォームを送信する前に読み、同意しなければならないプライバシーポリシーへのリンクを含む。

4.フィードバックメッセージ

  • エラーメッセージ: バリデーションでエラーが発生した場合、フォーム上部のブロックに表示されます。
  • 成功メッセージ: フォームの送信に成功すると、成功メッセージが緑色、14px、太字で表示されます!メッセージは送信されました。このテキストと書式はコードで変更できます。ここに表示されている黄色の背景、フォームを含むボックスのボーダーとシャドウ、その他の外部要素などの残りのスタイルは、GenerateBlocksコンテナで追加されるため、コードには含まれていません。

5.パーソナライゼーション

  • Captchaテキスト:カスタマイズ可能(デフォルト:"Are you human? Solve this sum:")。
  • 禁止ワード:カンマ区切りで禁止ワードのリストを追加できる。
  • Google reCAPTCHA: オプション。キャプチャのサイトキーとシークレットキーを 設定し、コードに追加する 場合のみ追加されます。

6.パフォーマンス

このコードは、ショートコードが存在するかどうかをチェックし、ショートコードが存在しない場合は何も表示しないので、ショートコードが追加されたページまたは投稿でのみ実行されます。

表示されているパフォーマンスが最適である。

お問い合わせフォームのページパフォーマンス

インストールと設定方法

1.コードをコピーして追加する

  1. WordPressテーマのfunctions.phpファイルを開きます(テーマを変更したりCode Snippetsを使用したくない場合は、カスタムプラグインを作成します)。
  2. 完全なフォームコードをコピーして、functions.phpファイルに貼り付けます。

2.Google reCAPTCHAを設定する(オプション)

  1. Google reCAPTCHAにアクセスする。
  2. reCAPTCHA v2を選択し、"I'm not a robot "チェックボックスを選択する。
  3. あなたのウェブサイトを登録し、キーを取得します
  4. フォームのコード中で、'YOUR_SITE_KEY''YOUR_SECRET_KEY'をあなたが取得したキーに置き換えて
    ください。

3.禁止ワードの設定(オプション)

1 - フォームコードの中で、次の行を見つける:

$palabras_prohibidas = ' ';

2 - ブロックしたい単語をカンマで区切って追加する。例えば

$palabras_prohibidas = 'caca,culo,pedo,pis';

単語をブロックしたくない場合は、変数を空のままにしてください。

4.合計のキャプチャテキストをカスタマイズする(オプション)

フォーム・コードの中で、次の行を探してください:

<label for="captcha">¿Eres humano? Resuelve esta suma: <strong><?php echo $num1; ?> + <?php echo $num2; ?> = </strong></label>

あなたは人間ですか?この和を解きなさい:"を表示したいものに変更する。

5.プライバシーポリシーのURLを追加する

この行で、例のURLをあなたのサイトのプライバシー・ポリシーのURLに置き換えてください:

$politica_privacidad_url = 'https://tuweb.com/declaracion-de-privacidad/';

6.ショートコード

フォームを表示したいページまたは投稿にショートコードを追加します。

[formulario_contacto]

そして、数学的なキャプチャを複雑にしたり、両方のキャプチャを同時に有効にしたりして、執拗なスパマーがこっそりと侵入するのを防ぐために、使用状況を観察する必要があります。コードは常に改善することができ、デバッグと最適化が可能です。他の言語で使用する必要がある場合は、翻訳することもできます。

その結果によってコードを変更したり改良したりする場合は、ここに注釈を加える。

コード

//Crea un shortcode que genera un formulario de contacto para añadir en cualquier página o post de tu blog. Código actualizado en https://jrmora.com/formulario-contacto-wordpress-sin-plugin/
// Shortcode para mostrar el formulario de contacto
function contacto_form_shortcode() {
    // Verificar si el shortcode está presente en el contenido actual
    if (!has_shortcode(get_the_content(), 'formulario_contacto')) {
        return ''; // Si no está el shortcode, no mostrar nada
    }

    ob_start(); // Iniciar el buffer de salida

    // Claves de Google reCAPTCHA (cambia estas por las tuyas)
    $site_key = 'TU_CLAVE_DEL_SITIO'; // Clave del sitio de reCAPTCHA
    $secret_key = 'TU_CLAVE_SECRETA'; // Clave secreta de reCAPTCHA

    // Verificar si las claves son las predeterminadas
    $recaptcha_enabled = ($site_key !== 'TU_CLAVE_DEL_SITIO' && $secret_key !== 'TU_CLAVE_SECRETA');

    // Lista de palabras prohibidas (separadas por comas)
    // Ejemplo: $palabras_prohibidas = 'spam,publicidad,oferta';
    $palabras_prohibidas = ''; // No hay palabras prohibidas por defecto

    // Convertir la lista de palabras prohibidas en un array
    $palabras_prohibidas_array = !empty($palabras_prohibidas) ? explode(',', $palabras_prohibidas) : [];

    // Variables para almacenar errores
    $errors = [];

    // Verificar si el formulario ha sido enviado
    if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['contacto_nonce'])) {
        // Verificar el nonce para seguridad
        if (!wp_verify_nonce($_POST['contacto_nonce'], 'contacto_form_nonce')) {
            $errors[] = 'Error de seguridad. Inténtalo de nuevo.';
        } else {
            // Validar el captcha de suma
            $captcha = sanitize_text_field($_POST['captcha']);
            $captcha_correct = sanitize_text_field($_POST['captcha_correct']);

            if ($captcha !== $captcha_correct) {
                $errors[] = 'El resultado de la operación es incorrecto. Inténtalo de nuevo.';
            } else {
                // Validar la aceptación de la política de privacidad
                if (!isset($_POST['aceptar_privacidad'])) {
                    $errors[] = 'Debes aceptar la política de privacidad para enviar el formulario.';
                } else {
                    // Validar Google reCAPTCHA (solo si está habilitado)
                    if ($recaptcha_enabled) {
                        if (isset($_POST['g-recaptcha-response'])) {
                            $recaptcha_response = sanitize_text_field($_POST['g-recaptcha-response']);
                            $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
                            $recaptcha_data = [
                                'secret' => $secret_key,
                                'response' => $recaptcha_response,
                            ];

                            $recaptcha_options = [
                                'http' => [
                                    'method' => 'POST',
                                    'header' => 'Content-Type: application/x-www-form-urlencoded',
                                    'content' => http_build_query($recaptcha_data),
                                ],
                            ];

                            $recaptcha_context = stream_context_create($recaptcha_options);
                            $recaptcha_result = file_get_contents($recaptcha_url, false, $recaptcha_context);
                            $recaptcha_json = json_decode($recaptcha_result);

                            if (!$recaptcha_json->success) {
                                $errors[] = 'Por favor, verifica que no eres un robot.';
                            }
                        } else {
                            $errors[] = 'Por favor, completa el reCAPTCHA.';
                        }
                    }

                    // Si no hay errores, procesar el formulario
                    if (empty($errors)) {
                        $nombre = sanitize_text_field($_POST['nombre']);
                        $email = sanitize_email($_POST['email']);
                        $mensaje = sanitize_textarea_field($_POST['mensaje']);

                        // Validar campos obligatorios
                        if (empty($nombre)) {
                            $errors[] = 'El campo nombre es obligatorio.';
                        }
                        if (empty($email)) {
                            $errors[] = 'El campo email es obligatorio.';
                        }
                        if (empty($mensaje)) {
                            $errors[] = 'El campo mensaje es obligatorio.';
                        }

                        // Validar que no se hayan añadido enlaces en los campos
                        if (preg_match('/http|www|\[url|\[link|href=/i', $nombre . $mensaje)) {
                            $errors[] = 'No se permiten enlaces en los campos del formulario.';
                        }

                        // Validar que el mensaje tenga al menos 15 caracteres
                        if (strlen($mensaje) < 15) {
                            $errors[] = 'El mensaje debe tener al menos 15 caracteres.';
                        }

                        // Validar palabras prohibidas (solo si hay palabras en la lista)
                        if (!empty($palabras_prohibidas_array)) {
                            foreach ($palabras_prohibidas_array as $palabra) {
                                if (stripos($mensaje, $palabra) !== false) {
                                    $errors[] = 'El mensaje contiene palabras no permitidas.';
                                    break; // Detener la validación al encontrar una palabra prohibida
                                }
                            }
                        }

                        // Si no hay errores, enviar el correo
                        if (empty($errors)) {
                            $to = get_option('admin_email'); // Correo del administrador
                            $subject = 'Nuevo mensaje de contacto desde el sitio web';
                            $headers = array('Content-Type: text/html; charset=UTF-8', 'From: ' . $nombre . ' <' . $email . '>');

                            $body = "<p><strong>Nombre:</strong> $nombre</p>";
                            $body .= "<p><strong>Email:</strong> $email</p>";
                            $body .= "<p><strong>Mensaje:</strong> $mensaje</p>";

                            if (wp_mail($to, $subject, $body, $headers)) {
                                // Redirigir para evitar reenvío al refrescar la página
                                wp_redirect(add_query_arg('contacto', 'success', wp_get_referer()));
                                exit;
                            } else {
                                $errors[] = 'Hubo un error al enviar el mensaje. Inténtalo de nuevo.';
                            }
                        }
                    }
                }
            }
        }
    }

    // Mostrar mensaje de éxito después de la redirección
    if (isset($_GET['contacto']) && $_GET['contacto'] === 'success') {
        echo '<p style="font-size: 14px; font-weight: bold; color: green;">¡Gracias! Tu mensaje ha sido enviado.</p>';
    }

    // Generar un captcha de suma de dos números aleatorios entre 1 y 9
    $num1 = rand(1, 9); // Primer número aleatorio entre 1 y 9
    $num2 = rand(1, 9); // Segundo número aleatorio entre 1 y 9
    $captcha_result = $num1 + $num2; // Resultado de la suma

    // URL de la política de privacidad
    $politica_privacidad_url = 'https://tuweb.com/declaracion-de-privacidad/';

    // Mostrar el formulario
    ?>
    <?php if (!empty($errors)) : ?>
        <div style="color: red; margin-bottom: 20px;">
            <?php foreach ($errors as $error) : ?>
                <p><?php echo esc_html($error); ?></p>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

    <form action="" method="post">
        <p>
            <label for="nombre">Nombre:</label><br>
            <input type="text" name="nombre" id="nombre" value="<?php echo isset($nombre) ? esc_attr($nombre) : ''; ?>" required>
        </p>
        <p>
            <label for="email">Email:</label><br>
            <input type="email" name="email" id="email" value="<?php echo isset($email) ? esc_attr($email) : ''; ?>" required>
        </p>
        <p>
            <label for="mensaje">Mensaje:</label><br>
            <textarea name="mensaje" id="mensaje" rows="5" required><?php echo isset($mensaje) ? esc_textarea($mensaje) : ''; ?></textarea>
        </p>
        <p>
            <label for="captcha">¿Eres humano? Resuelve esta suma: <strong><?php echo $num1; ?> + <?php echo $num2; ?> = </strong></label><br>
            <input type="text" name="captcha" id="captcha" required>
            <input type="hidden" name="captcha_correct" value="<?php echo $captcha_result; ?>">
        </p>
        <?php if ($recaptcha_enabled) : ?>
            <p>
                <div class="g-recaptcha" data-sitekey="<?php echo esc_attr($site_key); ?>"></div>
                <script src="https://www.google.com/recaptcha/api.js" async defer></script>
            </p>
        <?php endif; ?>
        <p>
            <input type="checkbox" name="aceptar_privacidad" id="aceptar_privacidad" required>
            <label for="aceptar_privacidad">He leído y acepto la <a href="<?php echo esc_url($politica_privacidad_url); ?>" target="_blank">política de privacidad</a>.</label>
        </p>
        <p>
            <?php wp_nonce_field('contacto_form_nonce', 'contacto_nonce'); ?>
            <input type="submit" value="Enviar">
        </p>
    </form>
    <?php

    return ob_get_clean(); // Devolver el contenido del buffer
}
add_shortcode('formulario_contacto', 'contacto_form_shortcode');

関連記事