Вопрос или проблема
Я хочу сохранить/обновить пользовательское метаполе с помощью ajax на фронтенде. Это поле должно содержать список ID постов. Не должно быть дублирующихся ID.
Моя проблема в том, что значение моего поля сохраняется в виде многомерного массива каждый раз, когда я его обновляю.
Например, сохраненные данные выглядят следующим образом:
Array ( [0] => Array ( [0] => Array ( [0] => [1] => 70 [2] => 79 ) [1] => 79 ) [1] => 93 )
Мне нужен/хочется одинарный массив.
Я пробовал разные вещи относительно параметра $single
функции get_user_meta()
, так как, похоже, это и есть проблема. Но я не смог найти решение.
Я думаю, что проблема в формате значения, которое я получаю с помощью get_user_meta()
.
В моей функции enqueue я использую wp_localize_script
, чтобы добавить значения в мой пользовательский JS файл. Здесь я хотел бы проверить, было ли значение уже сохранено, и отправить это значение в JS файл.
(Я добавил комментарии в код)
function my_custom_enqueue() {
if ( is_user_logged_in() ) {
wp_enqueue_script( 'ajax-script', plugins_url('ajax.js', __FILE__), array('jquery') );
$current_user = wp_get_current_user();
$saved_ids = get_user_meta($current_user->ID, 'postlist', false);
// если изменить на true, jquery больше не работает, но если true, это также может быть массив
// сделать что-то, если $saved_ids пустой ?! проверить, является ли он массивом?!
wp_localize_script( 'ajax-script', 'my_ajax_object', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'saved_ids' => $saved_ids,
) );
}
}
add_action( 'wp_enqueue_scripts', 'my_custom_enqueue' );
В моем файле ajax.js
:
jQuery(document).ready(function($){
//получить значение $saved_ids
var postIdsToCompare = my_ajax_object.saved_ids;
$(document).on('click', '.add-to-list', function(e) {
e.preventDefault();
// получить ID поста из data-id элемента
var idToAdd = $(this).attr('data-id');
// проверить, существует ли ID поста в postIdsToCompare
// это больше не работает из-за многомерных массивов
var found = $.inArray(idToAdd, postIdsToCompare);
if (found >= 0) {
// Элемент найден, удалить его из массива
postIdsToCompare.splice(found, 1);
} else {
// Элемент не найден, добавить его в массив
postIdsToCompare.push(idToAdd);
}
var data = {
'action': 'make_post_list', // имя функции php "wp_ajax_make_post_list"
'ids_to_compare': postIdsToCompare, // для использования $_POST['ids_to_compare']
};
$.post(my_ajax_object.ajax_url, data, function(response) {
alert('Добавлено');
});
});
});
Моя функция обратного вызова ajax для сохранения/обновления поля.
add_action( 'wp_ajax_make_post_list', 'make_post_list_callback' );
function make_post_list_callback() {
global $wpdb; // так вы получаете доступ к базе данных
// Убедитесь, что у нас есть данные, необходимые для продолжения
if( ! isset( $_POST ) || empty( $_POST ) || ! is_user_logged_in() ) {
exit;
}
$user_id = get_current_user_id();
$saved_ids = get_user_meta($user_id, 'postlist', true);
$ids_to_compare = $_POST['ids_to_compare'];
//сохранить пользовательские метаданные здесь
update_user_meta(
$user_id, // ID пользователя
'postlist', // ключ метаданных
$ids_to_compare, // значение метаданных
$saved_ids // предыдущее значение, пробовал и без него
);
wp_die();
}
Я хотел обновить этот старый вопрос.
Я смог это сделать или, по крайней мере, я разобрался с сохранением.
Спасибо Тому Дж. Ноуэллу за его вклад. Я действительно рассматривал использование REST API, да, я посмотрел несколько введений, но это оказалось слишком сложно для меня. REST API, как и AJAX, для меня довольно новы, и я действительно не работал с этими вещами. Я особенно планирую изучить использование REST API.
Учитывая это, я думаю, что код мог бы быть гораздо лучше и чище, но я просто поигрался и подумал, что должен опубликовать свой ответ в любом случае. Он также довольно прост…
Код Enqueue выглядит так:
function my_custom_enqueue() {
if ( is_user_logged_in() ) {
wp_enqueue_script( 'ajax-script', plugins_url('ajax.js', __FILE__), array('jquery') );
wp_localize_script( 'ajax-script', 'my_ajax_object', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
) );
}
}
add_action( 'wp_enqueue_scripts', 'my_custom_enqueue' );
Файл ajax.js
выглядит так:
jQuery(document).ready(function($){
$(document).on('click', '.add-to-list', function(e) {
e.preventDefault();
// получить ID поста из data-id элемента
var idToAdd = $(this).attr('data-id');
var data = {
'action': 'make_post_list', // имя функции php "wp_ajax_make_post_list"
'id_to_add': idToAdd, // для использования $_POST['ids_to_add']
};
$.post(my_ajax_object.ajax_url, data, function(response) {
console.log (response); // показать ответ в консоли
alert(response); // показать ответ в виде оповещения
});
});
});
И наконец, функция обратного вызова:
function make_post_list_callback() {
global $wpdb; // так вы получаете доступ к базе данных
// Убедитесь, что у нас есть данные, необходимые для продолжения
if( ! isset( $_POST ) || empty( $_POST ) || !is_user_logged_in() ) {
echo 'Ой! Попробуйте еще раз.';
exit;
}
$user_id = get_current_user_id();
// получить массив уже сохраненных ID
$saved_ids = get_user_meta($user_id, 'postlist', true);
// новый ID для добавления в массив
$id_to_add = $_POST['id_to_add'];
// проверить, существует ли ID уже в массиве,
// только если его нет, мы добавляем его
if( in_array( $id_to_add, $saved_ids ) ) {
echo 'Не удалось: Пост уже в списке.';
} else {
// если список пустой, инициализируйте его как пустой массив
if($saved_ids == ''){
$saved_ids = array();
}
// добавляем новый ID в массив
array_push( $saved_ids, $id_to_add );
if ( update_user_meta( $user_id, 'postlist', $saved_ids ) ) {
echo 'Успех!';
} else {
echo 'Не удалось: Не удалось обновить метаданные пользователя.';
}
}
wp_die(); // это необходимо для немедленной остановки и возврата правильного ответа
}
add_action( 'wp_ajax_make_post_list', 'make_post_list_callback' );
Таким образом, вошедший в систему пользователь может нажимать кнопку на посте, ID поста затем сохраняется в метаданных пользователя, сохраненные метаданные выглядят следующим образом:
Array ( [0] => 70 [1] => 76 [2] => 343 [3] => 375 [4] => 40 )
Ответ или решение
Обновление пользовательских метаданных через AJAX с фронтенда: Проблема сохранения
Вам необходимо обновить пользовательское мета поле через AJAX с фронтенда, но возникла проблема с тем, что сохраняемые данные представляют собой многомерный массив, в то время как требуется одномерный массив. Обсудим решение этой задачи, уделяя внимание каждому шагу процесса.
Шаг 1: Подключение и передача данных через AJAX
В начале необходимо правильно организовать процесс передачи данных из PHP в JavaScript, чтобы корректно работать с сохраненными метаданными. Ваша функция my_custom_enqueue
выглядит правильно, но рекомендуется убедиться, что вы правильно обрабатываете возвращаемые значения из get_user_meta
.
function my_custom_enqueue() {
if (is_user_logged_in()) {
wp_enqueue_script('ajax-script', plugins_url('ajax.js', __FILE__), array('jquery'));
$current_user = wp_get_current_user();
$saved_ids = get_user_meta($current_user->ID, 'postlist', true);
// Если $saved_ids не является массивом, инициализируем его как пустой массив
if (!is_array($saved_ids)) {
$saved_ids = array();
}
wp_localize_script('ajax-script', 'my_ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php'),
'saved_ids' => $saved_ids
));
}
}
add_action('wp_enqueue_scripts', 'my_custom_enqueue');
Шаг 2: Обработка на фронтенде
Следующим этапом будет обработка клика по кнопке "Добавить в список". Измените your ajax.js
файл, чтобы включать логику, которая добавляет или удаляет ID поста из массива saved_ids
.
jQuery(document).ready(function($) {
var postIdsToCompare = my_ajax_object.saved_ids;
$(document).on('click', '.add-to-list', function(e) {
e.preventDefault();
var idToAdd = $(this).attr('data-id');
// Проверка существования ID в массиве
var foundIndex = postIdsToCompare.indexOf(idToAdd);
if (foundIndex !== -1) {
// ID найден, удаляем его
postIdsToCompare.splice(foundIndex, 1);
} else {
// ID не найден, добавляем его
postIdsToCompare.push(idToAdd);
}
var data = {
action: 'make_post_list',
ids_to_compare: postIdsToCompare
};
$.post(my_ajax_object.ajax_url, data, function(response) {
console.log(response);
alert(response);
});
});
});
Шаг 3: Серверная обработка с помощью AJAX
Теперь перейдем к функции обработки AJAX в PHP. Необходимо корректно обрабатывать массив ID и предотвращать дубликаты при добавлении новых идентификаторов.
add_action('wp_ajax_make_post_list', 'make_post_list_callback');
function make_post_list_callback() {
if (!isset($_POST['ids_to_compare']) || !is_user_logged_in()) {
echo 'Ошибка: Не удалось обновить список.';
wp_die();
}
$user_id = get_current_user_id();
$saved_ids = get_user_meta($user_id, 'postlist', true);
// Убедитесь, что $saved_ids - это массив
if (!is_array($saved_ids)) {
$saved_ids = array();
}
$ids_to_compare = $_POST['ids_to_compare'];
// Сохраните данные
if (update_user_meta($user_id, 'postlist', $ids_to_compare)) {
echo 'Список успешно обновлен.';
} else {
echo 'Ошибка: Не удалось сохранить.';
}
wp_die();
}
Заключение
Теперь вы можете обновлять метаданные пользователя, добавляя или удаляя идентификаторы постов без формирования многомерного массива. Следуя этим шагам, вы гарантируете, что пользователь имеет возможность корректно управлять своими метаданными через фронтенд, а вы минимизируете возможность возникновения ошибок.
Если вы столкнетесь с любыми проблемами, не забывайте проверять как JavaScript, так и PHP для выявления возможных ошибок. Оптимизация кода может значительно улучшить как его читаемость, так и производительность, так что старайтесь следовать лучшим практикам программирования.