У меня есть веб-сайт WordPress, на котором я перечисляю всех пользователей (на основе подписки MemberPress), и пользователи могут сохранять других пользователей в качестве избранных. Функция хорошо работает при сохранении пользователя в качестве избранного, она сохраняет и обновляет, как следует, и она восстанавливается, когда я проверяю другое место/браузер.
Но удаление пользователя из избранного не работает. Вот что происходит:
Загрузка одной страницы, когда я нажимаю «удалить из избранного», она действует так, как будто я нажал «сохранить в избранное», текст «удалить из избранного» не меняется. При повторном нажатии на то же "удалить из избранного" текст меняется, а кнопка обновляется, по логу вроде все нормально, но при перезагрузке страницы ничего не сохраняется, и снова "удалить из избранного" '.
Другая ситуация, при загрузке страницы я нажимаю «сохранить в избранное» одного пользователя, а потом «сохранить в избранное» другого, вроде все нормально. Но при перезагрузке страницы фактически сохраняется только второй, первый возвращается к «сохранению в избранном». То же самое происходит, когда я нажимаю 3 или более «сохранить в избранное» и перезагружаю страницу, сохраняется только последняя.
Это мой список пользователей в PHP
function display_users($args = array(), $show_all_users = true)
{
$default_args = array(
'orderby' => 'name',
'order' => 'ASC',
'role' => 'subscriber',
'search' => '',
);
$args = wp_parse_args($args, $default_args);
$wp_user_query = new WP_User_Query($args);
if (!empty($wp_user_query->results)) {
$output = '<div class = "user-grid">';
foreach ($wp_user_query->results as $user) {
$mepr_user = new MeprUser($user->ID);
if (empty($mepr_user->active_product_subscriptions('ids'))) {
continue;
}
// Check if only favorites should be displayed
if (!$show_all_users) {
$user_id = get_current_user_id();
$favorites = get_user_meta($user_id, 'favorites', true);
if (!in_array($user->ID, $favorites)) {
// If user is not in favorites list, skip to the next user
continue;
}
}
$output .= '<div class = "user">';
$output .= '<a href = "' . get_author_posts_url($user->ID) . '">';
if (get_field('mepr_avatar_profile', 'user_' . $user->ID)) {
$avatar = get_field('mepr_avatar_profile', 'user_' . $user->ID);
$class = 'user-image-bw';
} else {
$avatar = '/wp-content/uploads/2023/04/new-color-community-1.png';
$class = 'default-image-avatar';
}
$output .= '<div class = "user-image">';
$output .= '<img class = "' . $class . '" src = "' . esc_url($avatar) . '" alt = "Author Avatar" />';
$output .= '</div>';
if (get_field('mepr_open_to_connect', 'user_' . $user->ID) == 'always-feel-free-to-reach-out') {
$output .= '<p class = "user-connect">Let\'s connect</p>';
}
$output .= '<div class = "user-name">' . get_field('first_name', 'user_' . $user->ID) . '</div>';
$output .= '<div class = "user-info">';
$current_work = get_field('mepr_current_work', 'user_' . $user->ID)[0];
$current_work = str_replace('-', ' ', $current_work);
$output .= '<p class = "user-current-work">' . $current_work . '</p>';
$output .= '</div>';
$output .= '</a>';
// Add favorite button
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$favorites = get_user_meta($user_id, 'favorites', true);
if (!is_array($favorites)) {
$favorites = array(); // set $favorites to an empty array if it is not already an array
}
$nonce = wp_create_nonce('save_user_favorites');
$output .= '<button class = "favorite-button" data-user-id = "' . $user->ID . '" data-favorites = "' . esc_attr(json_encode($favorites)) . '" data-is-favorite = "' . (in_array($user->ID, $favorites) ? 'true' : 'false') . '" data-nonce = "' . $nonce . '">' . (in_array($user->ID, $favorites) ? 'Remove from favorites' : 'Add to favorites') . '</button>';
}
$output .= '</div>';
}
$output .= '</div>';
} else {
$output = '<p>No users found.</p>';
}
return $output;
}
Это моя PHP-функция добавления в избранное
// save favorites function
function save_user_favorites() {
if (!isset($_POST['favorites'])) {
wp_send_json_error('Favorites not provided');
}
// Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'save_user_favorites')) {
wp_send_json_error('Invalid nonce');
}
// Check if user is logged in
if (!is_user_logged_in()) {
wp_send_json_error('User not logged in');
}
// Get user ID
$user_id = get_current_user_id();
// Get favorites
$favorites = isset($_POST['favorites']) ? $_POST['favorites'] : array();
// Update user meta
update_user_meta($user_id, 'favorites', $favorites);
wp_send_json_success();
}
add_action( 'wp_ajax_nopriv_save_user_favorites', 'save_user_favorites' );
add_action( 'wp_ajax_save_user_favorites', 'save_user_favorites');
Это мой jquery
$('.favorite-button').click(function(e) {
e.preventDefault();
var button = $(this);
var userId = button.data('userId');
var nonce = button.data('nonce');
// get existing favorites from the data attribute of the button
var favorites = button.data('favorites') || [];
// Add or remove user from favorites
if (userId !== "") {
const indexToRemove = favorites.indexOf(userId);
if (!favorites.includes(userId)) {
favorites.push(userId);
console.info(`User ${userId} added to favorites.`);
} else {
favorites.splice(indexToRemove, 1);
console.info(`User ${userId} removed from favorites.`);
}
// Save favorites to the user metadata via AJAX
$.post(ajaxurl, {
'action': 'save_user_favorites',
'favorites': favorites,
'nonce': nonce,
'user_id': userId // add user ID to request parameters,
})
.done(function(response) {
console.info('Favorites saved:', response);
// update the favorites attribute of the button
button.data('favorites', favorites);
})
.fail(function(xhr, status, error) {
console.info('Failed to save favorites:', error);
console.info('Server response:', xhr.responseText);
});
} else {
console.info(`Cannot add/remove user with empty ID`);
}
// Toggle button text and data attribute
button.text(favorites.includes(userId) ? 'Remove from favorites' : 'Add to favorites');
});
Я также попробовал другой способ для запроса ajax, сначала сохранив его как локальное хранилище и обновив список избранного при перезагрузке страницы. Это сработало очень хорошо, как и должно (добавление/удаление пользователей), но я получаю сообщение об ошибке при перезагрузке страницы, когда она пытается сохранить ее в избранном (не в локальном хранилище).
Что происходит при перезагрузке, так это то, что на самом деле он не сохраняется на стороне сервера, а только локально, и я получаю такой вывод на консоли:
from the update user Array []
from the update user Array []
from the update user Array []
from the update user Array(4) [ 420, 442, 449, 447 ]
from the update user Array []
И так продолжается, только с массивом значений тех, что я сохранил. Рядом написано, тоже много раз в firefox:
Failed to save favorites:
Server response: undefined
Failed to save favorites:
Server response: undefined
В хроме:
Favorites saved: {success: false, data: 'Favorites not provided'}
data: "Favorites not provided"
success: false
[[Prototype]]: Object
Это мой другой jQuery, который можно использовать вместо вышеперечисленного, для первого сохранения локально
// get existing favorites from localStorage, or initialize to empty array
var favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
$('.favorite-button').click(function(e) {
e.preventDefault();
var button = $(this);
var userId = button.data('userId');
// Add or remove user from favorites if userId is not empty
if (userId !== "") {
var isFavorite = button.data('isFavorite');
var nonce = button.data('nonce');
const userIdToRemove = userId; // Replace with the actual user ID you want to remove
const indexToRemove = favorites.indexOf(userIdToRemove);
// Add or remove user from favorites
if (!favorites.includes(userId)) {
favorites.push(userId);
console.info('user added to favorites')
} else {
favorites.splice(indexToRemove, 1);
console.info('user deleted from favorites')
}
// Save favorites to localStorage
localStorage.setItem('favorites', JSON.stringify(favorites));
// Save favorites to user metadata
$.post(ajaxurl, {
'action': 'save_user_favorites',
'favorites': favorites,
'nonce': nonce,
'user_id': userId // add user ID to request parameters
})
.done(function(response) {
console.info('Favorites saved:', response);
})
.fail(function(xhr, status, error) {
console.info('Failed to save favorites:', error);
console.info('Server response:', xhr.responseText);
});
update_local_storage(userId, favorites)
console.info('favorites saved to local storage', favorites)
// Toggle button text and data attribute
button.text(favorites.includes(userId) ? 'Remove from favorites' : 'Add to favorites');
}
});
// on page load, update button text based on stored favorites
$('.favorite-button').each(function() {
var button = $(this);
var userId = button.data('userId');
var isFavorite = button.data('isFavorite');
// check if user is in favorites
var favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
var isUserFavorite = favorites.includes(userId);
// set button text and data attribute based on result
button.text(isUserFavorite ? 'Remove from favorites' : 'Add to favorites');
button.data('isFavorite', isUserFavorite);
button.data('favorites', favorites);
});
// function to store favorites in localStorage
function update_local_storage(user_id, favorites) {
localStorage.setItem('favorites_' + user_id, JSON.stringify(favorites));
// console.info('localstorage', favorites)
}
function update_user_favorites(user_id, favorites, nonce) {
console.info('from the update user', favorites)
$.post(ajaxurl, {
'action': 'save_user_favorites',
'favorites': favorites,
'nonce': nonce,
'user_id': user_id // Use the user_id parameter instead of userId
})
.done(function(response) {
console.info('Favorites saved:', response);
})
.fail(function(xhr, status, error) {
console.info('Failed to save favorites:', error);
console.info('Server response:', xhr.responseText);
});
}
// update user metadata when page is unloaded
$(window).on('beforeunload', function() {
$('.favorite-button').each(function() {
var user_id = $(this).data('userId');
var nonce = $(this).data('nonce');
var favorites = JSON.parse(localStorage.getItem('favorites_' + user_id) || '[]');
// var favorites = [ 449, 487, 442, 474, 488, 457, 553, 559, 841]
// console.info({favorites})
update_user_favorites(user_id, favorites, nonce);
});
});
Я пытался регистрировать каждый шаг, и каждый раз кажется, что данные передаются правильно, и я не могу понять, почему это не работает. Какие-либо предложения?
Более того, лучше всего будет установить data.favorites= favorites, data.nonce= nonce и, наконец, data.user_id = user_id. Затем вы должны передать все эти данные в действие POST, например: $.post(ajaxurl, function( data ) { $( ".result" ).html( data );});
Привет @OrisSin, спасибо за твое сообщение. Я использую ajaxurl WordPress из admin-ajax.php, который работает нормально. К сожалению, изменение того, как я передаю данные, не меняется.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Может быть, что-то вроде этого
PHP на переднем плане
$output .= '<button class = "favorite-button ' . (in_array($user->ID, $favorites) ? 'is_favorite' : '') . '" data-user-id = "' . $user->ID . '" data-favorites = "' . esc_attr(json_encode($favorites)) . '" data-is-favorite = "' . (in_array($user->ID, $favorites) ? 'true' : 'false') . '" data-nonce = "' . $nonce . '">' . (in_array($user->ID, $favorites) ? 'Remove from favorites' : 'Add to favorites') . '</button>';
JS
$('.favorite-button').click(function(e) {
e.preventDefault();
var button = $(this);
var action = 'add';
var ajax = 0;
var userId = button.data('userId');
var nonce = button.data('nonce');
if (button.hasClass('is_favorite')) {
var action = 'remove';
}
if (userId !== "" && !ajax) {
ajax =1;
// Save favorites to the user metadata via AJAX
$.post(ajaxurl, {
'action': 'save_user_favorites',
'nonce': nonce,
'user_id': userId // add user ID to request parameters,
})
.done(function(response) {
ajax =0;
console.info('Favorites saved:', response);
if (action == 'add') {
button.addClass('is_favorite');
console.info(`User ${userId} added to favorites.`);
button.text( 'Remove from favorites' );
} else {
console.info(`User ${userId} removed from favorites.`);
button.text( 'Add to favorites');
}
})
.fail(function(xhr, status, error) {
console.info('Failed to save favorites:', error);
console.info('Server response:', xhr.responseText);
});
} else {
console.info(`Cannot add/remove user with empty ID`);
}
});
PHP
// save favorites function
function save_user_favorites() {
if (!isset($_POST['favorites'])) {
wp_send_json_error('Favorites not provided');
}
// Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'save_user_favorites')) {
wp_send_json_error('Invalid nonce');
}
// Check if user is logged in
if (!is_user_logged_in()) {
wp_send_json_error('User not logged in');
}
// Get user ID
$user_id = get_current_user_id();
// Get favorites
$favorites = get_user_meta($user_id, 'favorites', true) ;
if ( !$favorites ){
$favorites = [];
}
if ( in_array($_POST['user_id'], $favorites) ){
unset( $favorites[array_search($_POST['user_id'], $favorites)] );
} else {
$favorites[] = $_POST['user_id'];
}
// Update user meta
update_user_meta($user_id, 'favorites', $favorites);
wp_send_json_success();
}
add_action( 'wp_ajax_nopriv_save_user_favorites', 'save_user_favorites' );
add_action( 'wp_ajax_save_user_favorites', 'save_user_favorites');
Вы определенно сделали мой день (дни) @Galina! Мне просто нужно было добавить данные в сообщение в качестве параметра, например 'favorites': button.data('favorites'). Мне просто нужно посмотреть, почему при третьем клике или после удаления из избранного и повторного добавления текст не меняется (функционал работает идеально). Спасибо!
Чтобы кнопка не менялась, как объяснялось выше, я добавил button.removeClass('is_favorite'); к оператору ajax else в .done.
Вы правильно ссылаетесь на действие PHP в своем AJAX? Что такое
ajaxurl? Я нигде не вижу объявления этой переменной. Вероятно, это запрос, который выполняется неправильно, и поэтому вы не можете сохранить своих пользователей на стороне сервера.