Как создать виджет опроса в WordPress с помощью кода

Для сайта wppolls.ru мы рассмотрим, как создать собственный виджет опроса в WordPress, используя программный код. Такой подход позволит вам полностью контролировать внешний вид и логику работы опроса, не зависеть от сторонних плагинов и гибко интегрировать опросы в любую тему или сайт.

Почему стоит создавать виджет опроса самостоятельно

Готовые плагины зачастую предоставляют ограниченные возможности по кастомизации, могут влиять на производительность сайта и содержать лишний функционал. Создавая виджет опроса вручную, вы:

  • Избегаете лишнего кода и оптимизируете скорость загрузки страниц.
  • Получаете полный контроль над дизайном и поведением опроса.
  • Можете легко интегрировать опрос в любую часть сайта.
  • Учитесь работать с API WordPress и улучшаете навыки разработки.

Далее мы рассмотрим пошаговую реализацию такого виджета с базовым функционалом.

Создание класса виджета для опроса в WordPress

Для создания виджета в WordPress используется класс-наследник WP_Widget. Мы создадим класс Wppolls_Widget_Poll, который будет содержать логику вывода формы опроса и обработки ответов.

Основные методы класса:

  • __construct() — инициализация виджета с названием и описанием.
  • widget() — вывод контента виджета на сайте.
  • form() — вывод формы настроек виджета в админке.
  • update() — сохранение данных настроек.

Пример кода класса:

class Wppolls_Widget_Poll extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'wppolls_poll',
            'WPPolls: Опрос',
            ['description' => 'Виджет для создания простого опроса']
        );
    }

    public function widget($args, $instance) {
        echo $args['before_widget'];
        if (!empty($instance['question']) && !empty($instance['options'])) {
            $question = $instance['question'];
            $options = explode("\n", $instance['options']);

            echo '<form method="post" class="wppolls-poll-form">';
            echo '<p>' . esc_html($question) . '</p>';
            foreach ($options as $index => $option) {
                $option = trim($option);
                if ($option) {
                    echo '<p><label>';
                    echo '<input type="radio" name="wppolls_poll_option" value="' . esc_attr($index) . '" /> ' . esc_html($option);
                    echo '</label></p>';
                }
            }
            echo '<p><input type="submit" value="Голосовать" /></p>';
            echo '</form>';
        }
        echo $args['after_widget'];
    }

    public function form($instance) {
        $question = isset($instance['question']) ? $instance['question'] : '';
        $options = isset($instance['options']) ? $instance['options'] : "Вариант 1\nВариант 2\nВариант 3";
        ?>
        <p><label>Вопрос:<br /><input class="widefat" name="<?php echo esc_attr($this->get_field_name('question')); ?>" type="text" value="<?php echo esc_attr($question); ?>" /></label></p>
        <p><label>Варианты (каждый с новой строки):<br /><textarea class="widefat" rows="5" name="<?php echo esc_attr($this->get_field_name('options')); ?>"><?php echo esc_textarea($options); ?></textarea></label></p>
        <?php
    }

    public function update($new_instance, $old_instance) {
        $instance = [];
        $instance['question'] = sanitize_text_field($new_instance['question']);
        $instance['options'] = sanitize_textarea_field($new_instance['options']);
        return $instance;
    }
}

// Регистрация виджета
function wppolls_register_widget() {
    register_widget('Wppolls_Widget_Poll');
}
add_action('widgets_init', 'wppolls_register_widget');

Обработка голосов и хранение результатов

Чтобы опрос был функциональным, нужно реализовать обработку отправки формы и сохранение результатов голосования. Самый простой способ — использовать пользовательские опции WordPress или таблицу в базе данных.

Для начала добавим обработчик POST-запроса в functions.php или в файл плагина:

function wppolls_handle_vote() {
    if (isset($_POST['wppolls_poll_option'])) {
        $option_index = intval($_POST['wppolls_poll_option']);
        $poll_id = isset($_POST['wppolls_poll_id']) ? sanitize_text_field($_POST['wppolls_poll_id']) : 'default_poll';

        $votes = get_option('wppolls_votes_' . $poll_id, []);
        if (!isset($votes[$option_index])) {
            $votes[$option_index] = 0;
        }
        $votes[$option_index]++;
        update_option('wppolls_votes_' . $poll_id, $votes);

        // Перенаправляем для предотвращения повторной отправки формы
        wp_redirect($_SERVER['HTTP_REFERER']);
        exit;
    }
}
add_action('init', 'wppolls_handle_vote');

Чтобы связать голосование с конкретным виджетом, можно добавить скрытое поле с идентификатором опроса в форму.

Вывод результатов опроса в виджете

После голосования пользователю полезно видеть результаты. Добавим в метод widget() вывод процентов голосов для каждого варианта.

Пример доработки вывода:

public function widget($args, $instance) {
    echo $args['before_widget'];
    if (!empty($instance['question']) && !empty($instance['options'])) {
        $poll_id = $this->id;
        $question = $instance['question'];
        $options = explode("\n", $instance['options']);
        $votes = get_option('wppolls_votes_' . $poll_id, []);
        $total_votes = array_sum($votes);

        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['wppolls_poll_option'])) {
            echo '<p>Спасибо за ваш голос!</p>';
        }

        echo '<form method="post" class="wppolls-poll-form">';
        echo '<p>' . esc_html($question) . '</p>';

        foreach ($options as $index => $option) {
            $option = trim($option);
            if ($option) {
                $count = isset($votes[$index]) ? intval($votes[$index]) : 0;
                $percent = $total_votes > 0 ? round(($count / $total_votes) * 100) : 0;
                echo '<p><label>';
                echo '<input type="radio" name="wppolls_poll_option" value="' . esc_attr($index) . '" /> ' . esc_html($option);
                echo ' <strong>(' . $count . ' голосов, ' . $percent . '%)</strong>';
                echo '</label></p>';
            }
        }
        echo '<input type="hidden" name="wppolls_poll_id" value="' . esc_attr($poll_id) . '" />';
        echo '<p><input type="submit" value="Голосовать" /></p>';
        echo '</form>';
    }
    echo $args['after_widget'];
}

Советы по улучшению и безопасности

При создании собственного виджета опроса учитывайте следующие моменты:

  • Обязательно используйте wp_nonce_field() для защиты от CSRF-атак при отправке формы.
  • Сохраняйте результаты голосования в базе данных безопасно, избегайте SQL-инъекций.
  • Добавьте проверку, чтобы один пользователь не мог голосовать несколько раз (например, по IP или cookie).
  • Реализуйте кэширование результатов для уменьшения нагрузки.
  • Добавьте стили и скрипты для удобного и красивого интерфейса.

Создание собственного виджета — отличный способ глубже понять работу WordPress и настроить опросы под свои нужды без сторонних плагинов.

Как создать виджет опроса в WordPress с помощью кода
20.11.2025
Как создать прогноз по результатам опросов в WordPress
01.01.2026
Как создать свой shortcode для опросов в WordPress
17.11.2025
Как создать простой опрос в WordPress с помощью плагинов
07.11.2025
Автопубликация опросов в WordPress: настройка и автоматизация
30.11.2025