Проверка существования данных в базе WordPress - пользовательский плагин
Я пытаюсь добавить пользовательские данные в кастомную таблицу WordPress и хочу избежать дублирования записей. Мой код для проверки выглядит так:
global $wpdb;
$tablename=$wpdb->prefix."students"; // получаем имя таблицы с префиксом
$data=$wpdb->get_results("SELECT students_name, students_lastname FROM $tablename");
foreach($data as $da){
$da->students_name;
$da->students_lastname;
}
if(isset($_POST['submit'])){
$name=esc_attr($_POST['firstname']);
$surname=esc_attr($_POST['lastname']);
$email=sanitize_email($_POST['email']);
// проверяем, существует ли уже пользователь, чтобы не добавлять его дважды
if (
(is_email($email)) &&
(($da->students_name != $name) && ($da->students_lastname != $surname))
|| (($da->students_name == $name) && ($da->students_lastname != $surname))
|| (($da->students_name != $name) && ($da->students_lastname == $surname))
)
{
// назначаем новые данные для строк таблицы
$newdata = array(
'students_name'=>$name,
'students_lastname'=>$surname,
'students_email'=>$email,
'students_date'=>current_time( 'mysql' ),
);
// вставляем запись в базу данных
$wpdb->insert(
$tablename,
$newdata
);
// отображаем сообщение об успехе при добавлении студента
?>
<div class="wrap">
<div class="updated"><p>Студент добавлен!</p></div>
</div>
<?php
}else {
if(!is_email($email)){
echo '<div class="error"><p>Некорректный e-mail!</p></div>';
}else{
?
<div class="wrap">
<div class="error"><p>Студент уже существует!</p></div> <!-- класс error WordPress для уведомлений об ошибках --->
</div>
<?php
}
}
}
}
Проблема в том, что когда пользователь добавляет данные и если сразу же добавляет те же данные снова, появляется сообщение об ошибке и пользователь не добавляется. Но когда пользователь нажимает для просмотра добавленных записей (другая функция), а затем снова нажимает добавить нового студента, сообщение об ошибке не появляется и тот же пользователь добавляется дважды или более. Есть идеи?

Вы можете значительно улучшить свой код. Я буду использовать email в качестве уникального идентификатора студента, так как у меня точно могут быть 2 студента с именем 'Иван Иванов'.
global $wpdb;
$tablename = $wpdb->prefix."students";
if(isset($_POST['submit'])){
$name = esc_attr($_POST['firstname']);
$surname = esc_attr($_POST['lastname']);
$email = sanitize_email($_POST['email']);
if(!is_email($email)) {
//Отображение ошибки невалидного email и выход
echo '<div class="error"><p>Неверный e-mail!</p></div>';
//return или exit
}
//Проверка существования пользователя с таким email
$datum = $wpdb->get_results("SELECT * FROM $tablename WHERE students_email = '".$email."'");
//Выведите объект $datum, чтобы увидеть как хранится количество.
//Я предполагаю, что ключ - 'count'
if($wpdb->num_rows > 0) {
//Отображение сообщения о дублирующейся записи и выход
?>
<div class="wrap">
<div class="error"><p>Студент уже существует!</p></div> <!-- wp класс error для уведомлений об ошибках --->
</div>
<?php
//return или exit
}
//Теперь, когда email уникален и валиден, можно добавить запись
//Назначение новых данных для строк таблицы
$newdata = array(
'students_name'=>$name,
'students_lastname'=>$surname,
'students_email'=>$email,
'students_date'=>current_time( 'mysql' ),
);
//Вставка записи в базу данных
$wpdb->insert(
$tablename,
$newdata
);
//Отображение сообщения об успешном добавлении студента
?>
<div class="wrap">
<div class="updated"><p>Студент добавлен!</p></div>
</div>
<?php }
Я избежал множества ненужных условий и циклов. Попробуйте этот вариант. Используйте JavaScript для очистки формы после успешного добавления записи.
Обновление:
Я использовал get_results
в соответствии с вашим запросом. Теперь вам нужно использовать $wpdb->num_rows
для подсчета количества результатов в условии.
Источники: https://codex.wordpress.org/Class_Reference/wpdb#SELECT_Generic_Results https://wordpress.org/support/topic/wpdb-mysql_num_rows

Думаю, мне нужны дополнительные условия, потому что сейчас студент всё равно добавляется, даже если email совпадает.

Выведите объект $datum
, чтобы проверить, возвращает ли он корректные данные. Добавьте echo внутрь условия count
, чтобы проверить, выполняется ли условие.

Ничего не выводится, как будто условие вообще не проверяется. Пробовал с var_dump и echo — ничего. Просто добавляет студента.

Затем вам нужно проверить SQL-запрос, выполнив его напрямую в базе данных.

Я исправил это другим SQL-запросом. Я сделал это с помощью $datum = $wpdb->get_results("SELECT COUNT(*) FROM $tablename WHERE students_email = $email", ARRAY_N);
и затем условием if($datum > 0 )
, и теперь это работает. Спасибо за помощь!

Отлично! Рад, что смог помочь. Пожалуйста, отредактируйте мой ответ и поместите туда правильный запрос. Возможно, это поможет кому-то в будущем. Кстати, в моем SQL-запросе была опечатка — я использовал student_email
вместо students_email
!

Я отредактировал ваш ответ с изменённым SQL-запросом и сразу заметил опечатку :D. Спасибо за помощь!

Думаю, вам нужно использовать $wpdb->query
вместо get_results
, так как вы проверяете массив на 0, когда на самом деле нужно проверять количество записей на 0. Хотя это работает, это неправильно.

Я был так сосредоточен на проверке, есть ли у пользователей одинаковый email, что забыл проверить добавление нового пользователя, и он не добавляется. Я всегда получаю сообщение об ошибке. Если я заменю get_results на query, новый пользователь добавляется, но он добавляется даже при совпадении email.

Давай еще раз проверю код. Кстати, взгляни на мой код... Я внес небольшое изменение в запрос и условие, которое его проверяет.

Потому что сравнение неверное. Ты сравниваешь объект напрямую с 0. Убери параметр ARRAY_N
и сделай var_dump объекта, чтобы увидеть, как возвращается count. Я обновляю свой код.

Верно, вам просто нужно использовать другую функцию. Почитайте кодекс, функция query
возвращает boolean при успешной операции. Я бы порекомендовал использовать get_row
или get_results
с параметром ARRAY_A
(ассоциативный массив). Затем проверьте количество элементов в условии. Используйте PHPMyAdmin для тестирования вашего запроса.

До сих пор добавляет пользователя с тем же email. Это уже сводит меня с ума.

Изменил код на $data = $wpdb->get_results("SELECT COUNT(*) FROM $tablename WHERE students_email = '".$email."'");
и теперь получаю ошибку, но просто не могу добавить нового студента.

Кажется, теперь разобрался.
$data = $wpdb->get_results("SELECT * FROM $tablename WHERE students_email = '".$email."'");if($wpdb->num_rows > 0){

Видимо, я не до конца понял. То работает, то нет. Я уже ничего не понимаю.

Чувак, выведи SQL-запрос и выполни его напрямую в БД. Сначала с существующим email, потом с несуществующим. Если запрос работает, то и мой код будет работать нормально. Ты в Скайпе?

Кажется, теперь работает с кодом выше. Наверное, просто какие-то глюки при тестировании. Спасибо за помощь. Да, я в Скайпе.
