ajax — Jak zaktualizować moją funkcję jquery/PHP, aby dodać/usunąć użytkownika jako ulubionego na liście użytkowników (WordPress)
Mam witrynę WordPress, w której wymieniam wszystkich użytkowników (w oparciu o subskrypcję MemberPress), a użytkownicy mogą zapisywać innych użytkowników jako ulubionych. Funkcja działa dobrze podczas zapisywania użytkownika jako ulubionego, przechowuje i aktualizuje tak, jak powinna, i jest pobierana, gdy sprawdzam w innym miejscu/przeglądarce.
Ale usunięcie użytkownika jako ulubionego nie działa. Oto co się dzieje:
-
Ładowanie jednej strony, kiedy klikam „usuń z ulubionych”, działa tak, jakbym kliknął „zapisz w ulubionych”, tekst „usuń z ulubionych” nie zmienia się. Po drugim kliknięciu tego samego „usuń z ulubionych”, tekst się zmienia, a przycisk jest aktualizowany, wydaje się, że wszystko idzie dobrze zgodnie z dziennikiem, ale po przeładowaniu strony nic nie jest zapisywane i wraca do „usuń z ulubionych” ’.
-
Inna sytuacja, podczas ładowania strony klikam „zapisz w ulubionych” jednego użytkownika, a potem „zapisz w ulubionych” innego, wydaje się, że wszystko jest w porządku. Ale po przeładowaniu strony faktycznie zapisywany jest tylko drugi, pierwszy wraca do „zapisz w ulubionych”. To samo dotyczy kliknięcia 3 lub więcej opcji „zapisz w ulubionych” i ponownego załadowania strony, zapisywana jest tylko ostatnia.
To jest moja lista użytkowników w 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;
}
To jest moja funkcja dodawania PHP do ulubionych
// 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');
To jest moje 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.log(`User ${userId} added to favorites.`);
} else {
favorites.splice(indexToRemove, 1);
console.log(`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.log('Favorites saved:', response);
// update the favorites attribute of the button
button.data('favorites', favorites);
})
.fail(function(xhr, status, error) {
console.log('Failed to save favorites:', error);
console.log('Server response:', xhr.responseText);
});
} else {
console.log(`Cannot add/remove user with empty ID`);
}
// Toggle button text and data attribute
button.text(favorites.includes(userId) ? 'Remove from favorites' : 'Add to favorites');
});
Próbując w inny sposób
Próbowałem również innego sposobu żądania ajax, najpierw przechowując go jako pamięć lokalną i aktualizując listę ulubionych podczas przeładowywania strony. To działało naprawdę dobrze i tak, jak powinno (dodawanie/usuwanie użytkowników), ale pojawia się błąd podczas ponownego ładowania strony, gdy próbuje zapisać ją w ulubionych (nie w pamięci lokalnej).
To, co dzieje się po przeładowaniu, polega na tym, że nie jest ono faktycznie zapisywane po stronie serwera, tylko lokalnie, i otrzymuję takie wyjście na konsoli:
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 []
I to trwa, z tylko tablicą z wartościami tych, które zapisałem. Obok niego jest napisane, również wiele razy w Firefoksie:
Failed to save favorites:
Server response: undefined
Failed to save favorites:
Server response: undefined
w chromie:
Favorites saved: {success: false, data: 'Favorites not provided'}
data: "Favorites not provided"
success: false
[[Prototype]]: Object
To jest mój drugi jQuery, którego można użyć zamiast powyższego, najpierw zapisując go lokalnie
// 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.log('user added to favorites')
} else {
favorites.splice(indexToRemove, 1);
console.log('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.log('Favorites saved:', response);
})
.fail(function(xhr, status, error) {
console.log('Failed to save favorites:', error);
console.log('Server response:', xhr.responseText);
});
update_local_storage(userId, favorites)
console.log('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.log('localstorage', favorites)
}
function update_user_favorites(user_id, favorites, nonce) {
console.log('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.log('Favorites saved:', response);
})
.fail(function(xhr, status, error) {
console.log('Failed to save favorites:', error);
console.log('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.log({favorites})
update_user_favorites(user_id, favorites, nonce);
});
});
Próbowałem rejestrować każdy krok i za każdym razem wygląda na to, że dane są przekazywane poprawnie i nie mogę dowiedzieć się, dlaczego to nie działa. Jakieś sugestie?