Форма обратной связи WordPress без плагина

На любом сайте должна быть форма для связи с администрацией. На WordPress реализовать её можно либо через плагин, например Contact Form 7, либо с помощью собственного кода. В этой статье я хотел бы поделиться своим решением как создать форму обратной связи WordPress без плагина.

Вариант формы, которую я предлагаю позволяет выводить форму через шорткод в любом месте вашего сайта, не содержит стилей CSS, их вы прописываете самостоятельно.

Рекомендация: все подобные манипуляции лучше всего проводить с использованием дочерней темы, чтобы в случае обновления родительской темы ваша работа не удалилась.

Готовый класс контактной формы

Первое, что необходимо сделать - это добавить файл class_wpgid_contact_form.php в папку с вашей темой и скопировать в него код, расположенный ниже.

Я добавляю файл в папку includes в дочерней теме.

<?php

/**
 * Class Wpgid_Contact_Form
 */

if ( ! class_exists( 'Wpgid_Contact_Form' ) ):

    class Wpgid_Contact_Form {

        public $settings = [
            'field_wrap_start'  => '<div class="contact-form__field">', // Обёртка поля начало
            'field_wrap_end'    => '</div>',                            // Обёртка поля конец
            'success_text'      => 'Сообщение успешно отправлено!',     // Сообщение об успешной отправке
            'submit_btn_text'   => 'Отправить сообщение',               // Надпись на кнопке "отправить"
        ];

        public $fields;

        public $admin_email;

        protected $nonce_action = 'wpgid_nonce_action';
        protected $nonce_name = 'wpgid_contactform_nonce';

        protected $errors;

        protected $success = false;
        

        public function __construct() {
            add_shortcode( 'contactform', [ $this, 'display_contact_form' ] );  // Регистрация шорткода
            add_action( 'init', array( $this, 'send_contact_form' ) );          // Подключение обработчика формы

            $this->admin_email = get_option( 'admin_email' );                   // Email администратора сайта (на него будут отправляться письма)
        }

        // Отображение формы
        public function display_contact_form() {

            $out = '';
            $out .= '<div class="contact-form">';

            if ( $this->success ) {
                $out .= '<div class="contact-form__success">';
                $out .= $this->settings['success_text'];
                $out .= '</div>';
            }
    
            if ( ! empty( $this->errors ) ) {
                $out .= '<ul class="contact-form__errors">';
                foreach ( $this->errors as $error ) {
                    $out .= '<li>' . $error . '</li>';
                }
                $out .= '</ul>';
            }
    
            if ( ! $this->success ) {
                $out .= '<form action="" method="post">';
                $out .= '<input type="email" name="email" style="display:none;">';
                $out .= $this->render_fields();
                $out .= '<input type="hidden" name="fields" value="' . base64_encode( json_encode($this->get_fields()) ) . '">';
                $out .= wp_nonce_field( $this->nonce_action, $this->nonce_name, true, false );
                $out .= '<input type="hidden" name="redirect_url" value="' . get_the_permalink() . '">';
                $out .= '<input type="hidden" name="submitted" value="submitted">';
                $out .= '<div class="contact-form__field">';
                $out .= '<button type="submit" class="contact-form__submit button">'. $this->settings['submit_btn_text'] .'</button>';
                $out .= '</div>';
                $out .= '</form>';
            }

            $out .= '</div>';

            return $out;

        }

        // Обработка формы
        public function send_contact_form() {

            // Check spam
            if ( ! empty( $_POST['email'] ) ) {
                return;
            }

            $body = '';

            if ( ! empty( $_POST['submitted'] ) && $_POST['submitted'] == 'submitted' ) {
    
                $valid = wp_verify_nonce( $_POST[ $this->nonce_name ], $this->nonce_action );
    
                if ( $valid ) {
    
                    $fields = json_decode( base64_decode( $_POST['fields'] ), true );
    
                    if( empty($fields) ) {
                        $this->errors[] = 'Извините, невозможно отправить форму.';
                    } else {
                        foreach ( $fields as $name => $field ) {
    
                            $field_name = $name;
                            if ( ! empty( $field['placeholder'] ) ) $field_name = $field['placeholder'];
                            if ( ! empty( $field['label'] ) ) $field_name = $field['label'];
        
                            if ( isset( $field['required'] ) && $field['required'] == 'required' && empty( $_POST[ $name ] ) ) {
                                $this->errors[] = 'Заполните поле ' . $field_name;
                            }
        
                            if ( ! empty( $name ) ) {
        
                                $body .= $field_name . ': ' . PHP_EOL . sanitize_text_field( $_POST[ $name ] ) . PHP_EOL . PHP_EOL;
        
                            }
                        }
        
                        $name = ( ! empty( $_POST['wpgid_name'] ) ) ? sanitize_text_field( $_POST['wpgid_name'] ) : '' ;
                        $from_email = ( ! empty( $_POST['wpgid_email'] ) ) ? sanitize_email( $_POST['wpgid_email'] ) : '' ;
                        if ( empty( $_POST['wpgid_subject'] ) || ! isset( $_POST['wpgid_subject'] ) ) {
                            $site_domain = $_SERVER['SERVER_NAME'];
                            $time_send = current_time('d.m.Y H:i');
                            $subject = sprintf( __( 'Сообщение с сайта %1s [%2s]' ), $site_domain, $time_send );
                        } else {
                            $subject = sanitize_text_field( $_POST['wpgid_subject'] );
                        }

                        if ( ! is_email( $from_email ) ) {
                            $this->errors[] = 'Неверный e-mail формат';
                        }
        
                        $body .= 'Сообщение от ' . get_site_url();
        
                        if ( empty( $this->errors ) ) {
        
                            $mail_from = $from_email;
                            $headers = 'From: '.$name.' <'.$mail_from.'>' . "\r\n" . 'Reply-To: ' . $from_email;
        
                            wp_mail( $this->admin_email, $subject, $body, $headers );
        
                            $this->success = true;
        
                        }
                    }    
                }
            }
            


        }

        // Преобразование полей в HTML формат
        public function render_fields(){
            $out = '';
            $fields = $this->get_fields();
            foreach ( $fields as $name => $field) {

                $attributes = '';
                $label = ( ! empty($field['label']) ) ? '<label for="' . $field['id'] . '" >' . $value . '</label>' : '';

                foreach ( $field as $attr => $value ) {
                    if( $attr == 'type' && $value == 'textarea' ) {
                        unset($value);
                    }
                    if ( ! empty( $value ) ) {
                        $attributes .= 'name='. $name .' ' . $attr . '="' . $value . '"';
                    }
                }

                switch ($field['type']) {
                    case 'text':
                        $out .= $this->settings['field_wrap_start'] . $label .'<input '. $attributes .' value=""/>'. $this->settings['field_wrap_end'];
                        break;
                    case 'email':
                        $out .= $this->settings['field_wrap_start'] . $label .'<input '. $attributes .' value=""/>'. $this->settings['field_wrap_end'];
                        break;
                    case 'textarea':
                        $out .= $this->settings['field_wrap_start'] . $label .'<textarea '. $attributes .'></textarea>'. $this->settings['field_wrap_end'];
                        break;
                }

            }
            return $out;
        }

        // Массив полей
        public function get_fields() {
            $fields = apply_filters( 'wpgid_contactform_fields', [
                'wpgid_name' => [
                    'type'          => 'text',
                    'label'         => '',
                    'required'      => 'required',
                    'id'            => 'wpgid_name',
                    'class'         => 'contact-form__name',
                    'placeholder'   => 'Ваше имя',
                ],
                'wpgid_email' => [
                    'type'          => 'email',
                    'label'         => '',
                    'required'      => 'required',
                    'id'            => 'wpgid_email',
                    'class'         => 'contact-form__email',
                    'placeholder'   => 'Email',
                ],
                'wpgid_subject' => [
                    'type'          => 'text',
                    'label'         => '',
                    'required'      => '',
                    'id'            => 'wpgid_subject',
                    'class'         => 'contact-form__subject',
                    'placeholder'   => 'Тема обращения',
                ],
                'wpgid_message' => [
                    'type'          => 'textarea',
                    'label'         => '',
                    'required'      => 'required',
                    'id'            => 'wpgid_message',
                    'class'         => 'contact-form__message',
                    'placeholder'   => 'Сообщение',
                    'rows'          => '6',
                    'cols'          => '30',
                ],
            ]);
            return $fields;
        }

    } // end class Wpgid_Contact_Form    

endif;
new Wpgid_Contact_Form;

Подключаем файл с классом

После того как мы добавили файл нужно его подключить, чтобы он заработал. Для этого в файле functions.php прописываем следующий код

// для дочерней темы
require get_stylesheet_directory() . '/includes/class_wpgid_contact_form.php';
// если используете родительскую тему
// require get_template_directory() . '/includes/class_wpgid_contact_form.php';

Стили для формы контактов

Форма не подключает никакие стили CSS, если вам нужно её визуально настроить, то вы можете использовать классы, предложенные ниже. Добавьте их в файл стилей для вашей темы и настройте под внешний вид вашего сайта.

.contact-form{}             /* Обертка формы */
.contact-form__field{}      /* Обертка поля */
.contact-form label{}       /* Label */
.contact-form input{}       /* Input */
.contact-form textarea{}    /* Textarea */
.contact-form__success{}    /* Сообщение об успешной отправке */
.contact-form__errors{}     /* Список ошибок  */
.contact-form__errors li {} /* Ошибка из списка */

Вывод формы на сайте

В статьях и записях вы можете использовать шорткод [contactform]

В коде можно использовать фанкцию echo do_shortcode( '[contactform]' );

На этом всё! Если вам пригодилась данная форма оставьте комментарий, а так же не стесняйтесь задавать вопросы или свои предложения.

Дима
С движком WordPress познакомился в 2015 году и сразу начал его осваивать. Очень понравилось копаться в коде и создавать что-то новое. Создаю темы и плагины WP в первую очередь для себя, но возможно мои наработки и куски кода кому-то пригодятся, поэтому создал этот блог.
Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

PHP JS HTML CSS