Вопрос или проблема
Я использую эту функцию, чтобы получить все товары одной категории в AJAX-запросе.
function get_products()
{
$cat_id = $_POST['category'];
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => '12',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id', //Это необязательно, так как по умолчанию используется 'term_id'
'terms' => $cat_id,
'operator' => 'IN' // Возможные значения: 'IN', 'NOT IN', 'AND'.
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog', // Возможно, также 'exclude-from-search'
'operator' => 'NOT IN'
)
)
);
$products = new WP_Query($args);
echo json_encode($products);
wp_die();
}
Затем я получил данные каждого товара, но не все данные каждого товара.
ID: 75
post_author: "4"
post_date: "2020-04-21 08:45:26"
post_date_gmt: "2020-04-21 08:45:26"
post_content: "samsung galaxy - очень привлекательный мобильный телефон"
post_title: "samsung galaxy"
post_excerpt: "это samsung galaxy vvvvvvvvvvvv"
post_status: "publish"
comment_status: "open"
ping_status: "closed"
post_password: ""
post_name: "samsung-galaxy"
to_ping: ""
pinged: ""
post_modified: "2020-04-29 12:06:42"
post_modified_gmt: "2020-04-29 12:06:42"
post_content_filtered: ""
post_parent: 0
guid: "http:
menu_order: 0
post_type: "product"
post_mime_type: ""
comment_count: "1"
filter: "raw"
Я не могу найти изображение или цену товара, или цену со скидкой, или рейтинг.
Я хочу получить эти данные в скрипте.
function get_div(obj)
{
console.log("он здесь");
console.log(obj.ID);
console.log(obj.post_name);
console.log(obj.regular_price);=> возвращает undefined
}
В чем проблема???
Например, WP_Query используется только для получения стандартных данных постов. Дополнительные данные от плагинов, таких как WC, не будут получены.
Чтобы сделать пользовательский запрос
Если вы хотите использовать пользовательский запрос, вы можете использовать WC_Product_Query
Поместите следующее в файл functions.php вашей темы и сохраните JavaScript в отдельный PHP-файл. Быстрый тест использует стандартные образцы продуктов WC.
// в functions.php темы
// перед инициализацией, продукты не подготовлены, если просто позвонить в functions.php, так что для быстрого теста нужно поместить внутрь инициализации
add_action( 'init', 'ws365398_simple_test' );
function ws365398_simple_test() {
add_action('wp_enqueue_scripts', 'ws365398_enqueue_scripts', 101);
add_action( 'wp_ajax_my_action', 'get_products' );
add_action( 'wp_ajax_nopriv_my_action', 'get_products' );
}
// действия для ajax
function get_products()
{
if( !empty( $_POST['category'] ) ) {
$cat_id = $_POST['category'];
} else {
$cat_id = 19; // значение по умолчанию измените на свое, в тестовом случае убедитесь, что есть что-то по умолчанию
}
$args = array(
'status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => '12',
'tax_query' => array(
'relation' => 'AND', // отношение двух таксономических запросов
array(
'taxonomy' => 'product_cat',
'field' => 'term_id', //Это необязательно, так как по умолчанию используется 'term_id'
'terms' => $cat_id,
'operator' => 'IN' // Возможные значения: 'IN', 'NOT IN', 'AND'.
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog', // Возможно, также 'exclude-from-search'
'operator' => 'NOT IN'
)
)
);
$query = new WC_Product_Query($args);
$products = $query->get_products();
// преобразование в массив данных перед отправкой в json
$product_arr = [];
foreach ($products as $key => $product) {
$product_arr[] = $product->get_data();
}
// echo json_encode($product_arr);
wp_send_json_success( $product_arr ); // с флажком успеха и использовано напрямую
wp_die();
}
// подключение ajax скрипта
function ws365398_enqueue_scripts()
{
wp_enqueue_script('test-custom-scripts', get_theme_file_uri('ws365398-test-ajax.php'), array(), 't' . time(), true);
}
<?php
// ws365398-test-ajax.php
/** Загружает Bootstrap WordPress */
// измените на свой путь
require_once( '/project/wp-load.php' );
header("Content-type: text/javascript");?>
function test_ajax() {
let myData = {
action: 'my_action',
};
jQuery.post('<?php echo admin_url( 'admin-ajax.php' );?>', myData, function (response) {
if (response.success == true) {
console.log(response);
}
});
}
Чтобы протестировать, просто подготовьте вышеуказанные файлы с корректным путем для вашей среды.
Запустите test_ajax()
в инспекторе браузера, и вы увидите что-то вроде следующего:
Ответ или решение
Для получения всех продуктов определенной категории через AJAX-запрос в WordPress с использованием WooCommerce, необходимо учесть, что класс WP_Query
возвращает только стандартные поля постов, в то время как дополнительные данные, предоставляемые плагином WooCommerce, требуют использования класса WC_Product_Query
.
Ваша текущая реализация не включает данные, такие как изображение продукта, цена, скидочная цена и рейтинг, потому что вы не извлекаете эти данные из объекта продукта. Для этого вам потребуется изменить ваш код и следовать приведенным ниже рекомендациям.
Шаги для исправления кода:
-
Используйте
WC_Product_Query
для получения продуктов. Это позволит вам извлекать все данные, связанные с продуктами. -
Извлекайте нужные поля из объектов продуктов. Вы можете использовать методы класса
WC_Product
, чтобы получить цены, изображения и другие необходимые данные.
Пример кода:
// В вашем theme's functions.php
add_action('init', 'ws365398_simple_test');
function ws365398_simple_test() {
add_action('wp_enqueue_scripts', 'ws365398_enqueue_scripts', 101);
add_action('wp_ajax_my_action', 'get_products');
add_action('wp_ajax_nopriv_my_action', 'get_products');
}
function get_products() {
$cat_id = !empty($_POST['category']) ? $_POST['category'] : 19; // Убедитесь, что у вас есть корректный ID категории
$args = array(
'status' => 'publish',
'posts_per_page' => '12',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $cat_id,
'operator' => 'IN'
),
array(
'taxonomy' => 'product_visibility',
'field' => 'slug',
'terms' => 'exclude-from-catalog',
'operator' => 'NOT IN'
)
)
);
$query = new WC_Product_Query($args);
$products = $query->get_products();
// Массив для хранения данных продуктов
$product_arr = [];
foreach ($products as $product) {
$product_arr[] = array(
'id' => $product->get_id(),
'name' => $product->get_name(),
'price' => $product->get_regular_price(),
'sale_price' => $product->get_sale_price(),
'image' => wp_get_attachment_url($product->get_image_id()),
'rating' => $product->get_average_rating(),
);
}
// Отправка данных в формате JSON
wp_send_json_success($product_arr);
wp_die();
}
function ws365398_enqueue_scripts() {
wp_enqueue_script('test-custom-scripts', get_theme_file_uri('ws365398-test-ajax.php'), array('jquery'), '1.0', true);
}
Скрипт AJAX (ws365398-test-ajax.php
):
<?php
require_once('/project/wp-load.php');
header("Content-type: text/javascript");
?>
function test_ajax() {
let myData = {
action: 'my_action',
category: 19 // Укажите нужный ID категории
};
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', myData, function(response) {
if (response.success) {
console.log(response.data); // Вывод данных продуктов
} else {
console.log('Ошибка:', response);
}
});
}
Как протестировать:
- Убедитесь, что все изменения сохранены и файлы находятся в правильных папках.
- Откройте инструменты разработчика в браузере.
- Запустите функцию
test_ajax()
в консоли.
При корректной настройке вы получите JSON-ответ, содержащий все необходимые данные о продуктах, включая название, регулярную и скидочную цену, изображение и рейтинг.
Такая реализация даст вам полный доступ к данным о продуктах и позволит беспрепятственно использовать их в вашем JavaScript-коде.