Вопрос или проблема
Я пытаюсь создать функцию рейтинга постов с многокритериальной оценкой с простой формой и метаданными поста и пользователя.
Цель
Когда пользователи отправляют свои оценки, должно произойти две вещи:
1. Оценки сохраняются в метаданном поста под названием ‘wpd_rating’ следующим образом:
array(user id => array(
field1 => 5
field2 => 3
field3 => 4
),
another user id => array(
field1 => 2
field2 => 5
field3 => 4
)
)
2. Оценки сохраняются в метаданном пользователя под названием ‘plgn_rating’ следующим образом:
array(post id => array(
field1 => 5
field2 => 3
field3 => 4
),
another rated post id => array(
field1 => 2
field2 => 5
field3 => 4
)
)
Код (Очевидно не работает)
В single.php:
часть заголовка:
<?php // верх страницы
if ( isset( $_POST['drw_inventory'] ) && wp_verify_nonce($_POST['drw_inventory'],'update_drw_postmeta') )
{ // если проверка nonce прошла успешно.
global $post;
$postid = $post->ID;
$data = $_POST['wpd_function_rating'];
$data2 = $_POST['wpd_feature_rating'];
$data3 = $_POST['wpd_support_rating'];
$currentusr = get_current_user_id();
//*******************Часть метаполя поста****************************
//Получить существующие рейтинги пользователей для этого поста
$ls_up_votes = get_post_meta($postid, 'wpd_rating');
//если текущий пользователь уже оценивал, удалить оценку
foreach ( $ls_up_votes as $key => $value )
{
if ( $key == $currentusr )
{
unset( $ls_up_votes[$key] );
}
}
//Добавить метаполе поста 'wpd_rating' с этой структурой:
//array(userid => array('wpd_function_rating' => '3','wpd_feature_rating' => '5','wpd_support_rating' => '4',))
$up_vote = array($currentusr => array('wpd_function_rating' => $data,'wpd_feature_rating' => $data2,'wpd_support_rating' => $data3));
//добавление новых оценок пользователей одна за другой
$ls_up_voted = array_merge($ls_up_votes, $up_vote);
update_post_meta($postid,'wpd_rating',$ls_up_voted);
//*******************Часть пользовательского поля****************************
//Получить текущие рейтинги пользователя для этого поста
$user_rated_posts = get_user_meta($currentusr, 'plgn_rating',true);
foreach ( $user_rated_posts as $key => $value )
{
if ( $key == $postid )
{
unset( $user_rated_posts[$key] );
}
}
//добавить поле пользователя 'plgn_rating' с этой структурой
//(postid => array('wpd_function_rating' => '3','wpd_feature_rating' => '5','wpd_support_rating' => '4',))
$usr_vote = array($postid => array('wpd_function_rating' => $data,'wpd_feature_rating' => $data2,'wpd_support_rating' => $data3));
//добавление новых оценок пользователей одна за другой
$ls_up_voted = array_merge($user_rated_posts, $usr_vote);
update_user_meta($currentusr,'plgn_rating',$ls_up_voted);
}
?>
Форма:
<form method="post" action="">
<?php wp_nonce_field('update_drw_postmeta','drw_inventory'); ?>
<label>Это метка</label>
<input type="text" name="wpd_function_rating" value="" />
<input type="text" name="wpd_feature_rating" value="" />
<input type="text" name="wpd_support_rating" value="" />
<input type="submit" value="сохранить" />
</form>
Проблемы с текущим кодом
-
Массив не сохраняется в той структуре, как я задумал. Я уверен, что использую array_merge неправильно. Или вызываю get_post_meta неправильно.
-
Код не проверяет существующий рейтинг пользователя и не заменяет старые рейтинги на новые.
Обновление
Как предложил s_ha_dum, я попробовал это безрезультатно:
foreach ( $ls_up_votes as $key => $value ){
var_dump($key,$value);
if ( $key == $currentusr ){
unset( $ls_up_votes[$key] );
}
}
Когда я добавляю введенные пользователем данные 2 раза, команды unset должны удалить предыдущий массив, добавленный тем же пользователем, и добавить новый, вместо этого все добавляется дважды. Вот что я получаю:
Array ( [0] => Array ( [0] => [1] => Array ( [wpd_function_rating] => 33 [wpd_feature_rating] => 23 [wpd_support_rating] => 66 ) ) [1] => Array ( [wpd_function_rating] => 44 [wpd_feature_rating] => 11 [wpd_support_rating] => 32 ) )
Исходя из этого:
Array (
[0] => Array (
[wpd_function_rating] => 33
[wpd_feature_rating] => 12
[wpd_support_rating] => 66
)
)
Я могу заметить как минимум одну проблему. У вас есть вложенный массив, но вы перебираете только верхний уровень. Вот здесь:
foreach ( $ls_up_votes as $key => $value )
{
if ( $key == $currentusr )
{
unset( $ls_up_votes[$key] );
}
}
Попробуйте var_dump($key,$value)
внутри этого foreach
.
Я думаю, что ваше решение будет заключаться в том, чтобы передать третий параметр в get_post_meta
, чтобы он вернул “единственный” и не массив. Это немного странно, но работает несколько противоинтуитивно с сериализованными массивами, как я думаю, что у вас.
$ls_up_votes = get_post_meta($postid, 'wpd_rating');
Ответ или решение
Для реализации функционала многокритериальной оценки постов в WordPress с использованием post_meta
и user_meta
, важно учитывать правильное строгое соответствие структуре массива при обновлении и извлечении данных из базы данных. Рассмотрим более детально ваш код и исправления, которые можно внести, чтобы добиться желаемого результата.
Цель
При подаче пользователями оценок необходимо, чтобы выполнялись следующие два действия:
-
Оценка сохраняется в
post_meta
с именемwpd_rating
в следующем формате:array(user_id => array( field1 => 5, field2 => 3, field3 => 4 ))
-
Оценка сохраняется в
user_meta
с именемplgn_rating
в следующем формате:array(post_id => array( field1 => 5, field2 => 3, field3 => 4 ))
Анализ и исправление кода
Ваш код, похоже, имеет несколько проблем, связанных с неправильным использованием array_merge
и извлечением данных из метаданных. Давайте рассмотрим это подробнее шаг за шагом.
Извлечение данных из post_meta
При получении метаданных поста с помощью get_post_meta
, вам следует использовать третий параметр, чтобы получить данные в формате массива (а не массива массивов), как вы и планировали.
$ls_up_votes = get_post_meta($postid, 'wpd_rating', true);
Это обеспечит получение правильной структуры данных.
Обновление массива оценок
Теперь обновим код, чтобы корректно обрабатывать оценку:
- Удалите предыдущую оценку пользователя перед добавлением новой.
- Убедитесь, что вы формируете правильную структуру при добавлении оценок.
Обновленный код для сохранения оценок:
// Получаем существующие оценки поста
$ls_up_votes = get_post_meta($postid, 'wpd_rating', true);
if (!$ls_up_votes) {
$ls_up_votes = array();
}
// Удаляем старую оценку, если пользователь уже оставлял оценку
if (isset($ls_up_votes[$currentusr])) {
unset($ls_up_votes[$currentusr]);
}
// Формируем новую оценку
$up_vote = array(
$currentusr => array(
'wpd_function_rating' => $data,
'wpd_feature_rating' => $data2,
'wpd_support_rating' => $data3,
)
);
// Объединяем старые и новые оценки
$ls_up_votes = array_merge($ls_up_votes, $up_vote);
update_post_meta($postid, 'wpd_rating', $ls_up_votes);
// Теперь обновим user_meta аналогичным образом
$user_rated_posts = get_user_meta($currentusr, 'plgn_rating', true);
if (!$user_rated_posts) {
$user_rated_posts = array();
}
// Удаляем старую оценку для этого поста
if (isset($user_rated_posts[$postid])) {
unset($user_rated_posts[$postid]);
}
// Добавляем новую оценку
$usr_vote = array(
$postid => array(
'wpd_function_rating' => $data,
'wpd_feature_rating' => $data2,
'wpd_support_rating' => $data3,
)
);
// Объединяем старые и новые оценки
$user_rated_posts = array_merge($user_rated_posts, $usr_vote);
update_user_meta($currentusr, 'plgn_rating', $user_rated_posts);
Реализация формы
Ваш HTML-код формы выглядит правильно. Убедитесь, что добавлен заголовок для обработки:
<form method="post" action="">
<?php wp_nonce_field('update_drw_postmeta','drw_inventory'); ?>
<label>Оценка функции</label>
<input type="text" name="wpd_function_rating" value="" />
<label>Оценка функции</label>
<input type="text" name="wpd_feature_rating" value="" />
<label>Оценка поддержки</label>
<input type="text" name="wpd_support_rating" value="" />
<input type="submit" value="Сохранить" />
</form>
Заключение
После внесения этих изменений и проверки кода, ваш функционал многокритериальной оценки постов должен работать согласно задуманной логике. Этот подход позволит правильно сохранять оценки как в post_meta
, так и в user_meta
, обеспечивая корректное обновление данных при повторной подаче оценок.
Убедитесь, что при отладке код выводит возможные ошибки или предупреждения, чтобы упростить выявление дальнейших проблем.