Как в массив добавить функцию для загрузки элементов через ajax?

Ссылка скопирована
1 ответ

Работаю с WP, возникла необходимость подгружать карточки игр при нажатии кнопки "показать все". Данные передаю стандартные и из ACF полей. Проблема возникла с передачей данных из галереи ACF. Я написал функцию, которая отлично работает и выдает нужные данные для data-gallery. Но не получается вывести в массив $json['results'][] = array эту функцию, точнее не пойму какой должен быть синтаксис и куда саму функцию в коде поставить. Пробовал разные варианты вывода в $json['results'][] = array, к примеру так:

'gameGallery' => gameGallery(),

и как вариант пробовал запихнуть функцию в переменную и добавить ее в массив. Подскажите вообщем:)

Функция которая выводит галерею, которую нужно добавить в $json['results'][] = array :

function gameGallery() {    $images = get_field('gallery_game_img');    $i = 0;   if($images) {      foreach( $images as $image ) {       $numItems = count($images);       if(++$i === $numItems) {         echo """ . esc_url($image['url']) . """;       } else {         echo """ . esc_url($image['url']) . "",";       }      }        } }

function gameGallery() { $images = get_field('gallery_game_img'); $i = 0; if($images) { foreach( $images as $image ) { $numItems = count($images); if(++$i === $numItems) { echo """ . esc_url($image['url']) . """; } else { echo """ . esc_url($image['url']) . "","; } } } }

Функция основная в function.php

function get_games() {      $meta_q[] = array(         'key' => 'zakrep',         'value' => 'Да'     );     $limit = 8111111111111111111;     $exclude = array();         if(isset($_POST['exclude'])) {             $exclude = explode(',',$_POST['exclude']);         }      // параметры по умолчанию     $posts_reviews = new WP_Query( array(         'posts_per_page' => $limit,         'category'    => 0,         'orderby'     => 'title',         'order'       => 'ASC',         'include'     => array(),         'post__not_in'     => $exclude,         'meta_key'    => '',         'meta_value'  =>'',         'post_type'   => 'game-list',         'suppress_filters' => true,         'meta_query'    => array(             'relation'      => 'AND',             $meta_q         )      ) );        $posts_reviews = $posts_reviews->posts;      if(count($posts_reviews)<$limit) {          foreach( $posts_reviews as $post ){             $exclude[] = $post->ID;         }     } else {      }          $new_limit = $limit - count($posts_reviews);           $posts_reviews_others = new WP_Query( array(             'posts_per_page' => $new_limit,             'category'    => 0,             'orderby'     => 'title',             'order'       => 'ASC',             'include'     => array(),             'post__not_in'     => $exclude,             'meta_key'    => '',             'meta_value'  =>'',             'post_type'   => 'game-list',             'suppress_filters' => true, // подавление работы фильтров изменения SQL запроса           ) );         $posts_reviews_others = $posts_reviews_others->posts;         $posts_reviews = array_merge($posts_reviews,$posts_reviews_others);         global $post;      $json = array();     $front_id = get_option('page_on_front');      $price_box = get_field('array_price', $front_id);       foreach( $posts_reviews as $post ) {         setup_postdata($post);          $json['results'][] = array(             'post_id'=>$post->ID,             'title'=>get_the_title(),             'permalink' => get_permalink(),             'zakrep' => get_field('zakrep'),             'game_desc' => get_field('game_desc'),             'versus_game' => get_field('versus_game'),             'platform_os' => get_field('platform_os'),             'status_game' => get_field('status_game'),             'youtube_link' => get_field('youtube_link'),             'txt_basic' => $price_box['txt_basic'],             'txt_standart' => $price_box['txt_standart'],             'txt_premium' => $price_box['txt_premium'],             'txt_btn_basic' => $price_box['txt_btn_basic'],             'txt_btn_standart' => $price_box['txt_btn_standart'],             'txt_btn_premium' => $price_box['txt_btn_premium'],             'gallery_game_img' => get_field('gallery_game_img'),             'game_img_main' => get_field('game_img_main')         );      }      echo json_encode($json,true);     die();  }

function get_games() { $meta_q[] = array( 'key' => 'zakrep', 'value' => 'Да' ); $limit = 8111111111111111111; $exclude = array(); if(isset($_POST['exclude'])) { $exclude = explode(',',$_POST['exclude']); } // параметры по умолчанию $posts_reviews = new WP_Query( array( 'posts_per_page' => $limit, 'category' => 0, 'orderby' => 'title', 'order' => 'ASC', 'include' => array(), 'post__not_in' => $exclude, 'meta_key' => '', 'meta_value' =>'', 'post_type' => 'game-list', 'suppress_filters' => true, 'meta_query' => array( 'relation' => 'AND', $meta_q ) ) ); $posts_reviews = $posts_reviews->posts; if(count($posts_reviews)<$limit) { foreach( $posts_reviews as $post ){ $exclude[] = $post->ID; } } else { } $new_limit = $limit - count($posts_reviews); $posts_reviews_others = new WP_Query( array( 'posts_per_page' => $new_limit, 'category' => 0, 'orderby' => 'title', 'order' => 'ASC', 'include' => array(), 'post__not_in' => $exclude, 'meta_key' => '', 'meta_value' =>'', 'post_type' => 'game-list', 'suppress_filters' => true, // подавление работы фильтров изменения SQL запроса ) ); $posts_reviews_others = $posts_reviews_others->posts; $posts_reviews = array_merge($posts_reviews,$posts_reviews_others); global $post; $json = array(); $front_id = get_option('page_on_front'); $price_box = get_field('array_price', $front_id); foreach( $posts_reviews as $post ) { setup_postdata($post); $json['results'][] = array( 'post_id'=>$post->ID, 'title'=>get_the_title(), 'permalink' => get_permalink(), 'zakrep' => get_field('zakrep'), 'game_desc' => get_field('game_desc'), 'versus_game' => get_field('versus_game'), 'platform_os' => get_field('platform_os'), 'status_game' => get_field('status_game'), 'youtube_link' => get_field('youtube_link'), 'txt_basic' => $price_box['txt_basic'], 'txt_standart' => $price_box['txt_standart'], 'txt_premium' => $price_box['txt_premium'], 'txt_btn_basic' => $price_box['txt_btn_basic'], 'txt_btn_standart' => $price_box['txt_btn_standart'], 'txt_btn_premium' => $price_box['txt_btn_premium'], 'gallery_game_img' => get_field('gallery_game_img'), 'game_img_main' => get_field('game_img_main') ); } echo json_encode($json,true); die(); }

Вывожу через JS:

$.ajax({ 		url: '/wp-admin/admin-ajax.php', 		method: 'post', 		dataType: 'json', 		data: { 			action: 'get_games', 			exclude: ids 		}, 		success: function (data) {   			if (data['results']) {   				html = ''; 				for (i = 0; i < data['results'].length; i++) {  					html +='   <div data-slides="[""]" id="post_id_'+data['results'][i]['post_id']+'" data-post_id="'+data['results'][i]['post_id']+'" class="games__card game" data-name="'+data['results'][i]['title']+'" data-link="'+data['results'][i]['permalink']+'" data-description="'+data['results'][i]['game_desc']+'" ' + 						'data-version="'+data['results'][i]['versus_game']+'" ' +  						'data-device="'+data['results'][i]['platform_os']+'" ' + 						'data-assembly="'+data['results'][i]['status_game']+'"' + 						'data-slides="'+data['results'][i]['gallery_game_img']+'" ' + 						'data-video="'+data['results'][i]['youtube_link']+'" ' + 						'data-basic_txt="'+data['results'][i]['txt_basic']+'" ' + 						'data-standart_txt="'+data['results'][i]['txt_standart']+'" ' + 						'data-premium_txt="'+data['results'][i]['txt_premium']+'" ' + 						'data-btn_basic="'+data['results'][i]['txt_btn_basic']+'" ' + 						'data-btn_standart="'+data['results'][i]['txt_btn_standart']+'" ' + 						'data-btn_premium="'+data['results'][i]['txt_btn_premium']+'" ' + 						'data-img="'+data['results'][i]['game_img_main']+'">n' + 						'                      <img class="game__img" src="'+data['results'][i]['game_img_main']+'">n' + 						'                      <h4 class="game__title">'+data['results'][i]['title']+'</h4>n' + 						'                      <p class="game__subtitle">3 чита от 99 ₽</p>n' + 						'                    </div>';  				}  				$('.games__cards').append(html) 					//$('#games_card_ends').removeClass('load_progress') 				$('#get_more_games').remove() 				open_game_popup() 			} 		} 	})    }

$.ajax({ url: '/wp-admin/admin-ajax.php', method: 'post', dataType: 'json', data: { action: 'get_games', exclude: ids }, success: function (data) { if (data['results']) { html = ''; for (i = 0; i < data['results'].length; i++) { html +=' <div data-slides="[""]" id="post_id_'+data['results'][i]['post_id']+'" data-post_id="'+data['results'][i]['post_id']+'" class="games__card game" data-name="'+data['results'][i]['title']+'" data-link="'+data['results'][i]['permalink']+'" data-description="'+data['results'][i]['game_desc']+'" ' + 'data-version="'+data['results'][i]['versus_game']+'" ' + 'data-device="'+data['results'][i]['platform_os']+'" ' + 'data-assembly="'+data['results'][i]['status_game']+'"' + 'data-slides="'+data['results'][i]['gallery_game_img']+'" ' + 'data-video="'+data['results'][i]['youtube_link']+'" ' + 'data-basic_txt="'+data['results'][i]['txt_basic']+'" ' + 'data-standart_txt="'+data['results'][i]['txt_standart']+'" ' + 'data-premium_txt="'+data['results'][i]['txt_premium']+'" ' + 'data-btn_basic="'+data['results'][i]['txt_btn_basic']+'" ' + 'data-btn_standart="'+data['results'][i]['txt_btn_standart']+'" ' + 'data-btn_premium="'+data['results'][i]['txt_btn_premium']+'" ' + 'data-img="'+data['results'][i]['game_img_main']+'">n' + ' <img class="game__img" src="'+data['results'][i]['game_img_main']+'">n' + ' <h4 class="game__title">'+data['results'][i]['title']+'</h4>n' + ' <p class="game__subtitle">3 чита от 99 ₽</p>n' + ' </div>'; } $('.games__cards').append(html) //$('#games_card_ends').removeClass('load_progress') $('#get_more_games').remove() open_game_popup() } } }) }

Дополнительно:

Ответы:

Решение оказалось совсем другим

в function.php добавил

$images = array(); foreach ( get_field('gallery_game_img') as $image) { $images[] = $image['url'];         }

$images = array(); foreach ( get_field('gallery_game_img') as $image) { $images[] = $image['url']; }

Вывел в массиве стандартным образом:
'game_img_main' => get_field('game_img_main')

в JS:

html = ''; 				for (i = 0; i < data['results'].length; i++) { 					html_img = ''; 						if(data['results'][i]['gallery_game_img']) {   					//html_img = JSON.parse(data['results'][i]['gallery_game_img']);  							html_img = '["'+data['results'][i]['gallery_game_img'].join('","')+'"]'; 							console.log(html_img) 						}

html = ''; for (i = 0; i < data['results'].length; i++) { html_img = ''; if(data['results'][i]['gallery_game_img']) { //html_img = JSON.parse(data['results'][i]['gallery_game_img']); html_img = '["'+data['results'][i]['gallery_game_img'].join('","')+'"]'; console.log(html_img) }

Вывод:
data-slides="'+html_img+'"

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Backend-редакция Ответ

Если нужно через AJAX подгружать элементы и “добавить функцию в массив”, в WordPress лучше разделить задачу на две части: PHP-обработчик возвращает HTML/JSON, а JavaScript отправляет запрос и вставляет результат в DOM. Не смешивайте SQL, HTML и JS в одном куске кода.

PHP-обработчик:

add_action('wp_ajax_load_more_items', 'wt_load_more_items');
add_action('wp_ajax_nopriv_load_more_items', 'wt_load_more_items');
 
function wt_load_more_items() {
    check_ajax_referer('load_more_items', 'nonce');
 
    $page = max(1, (int) ($_POST['page'] ?? 1));
 
    $query = new WP_Query([
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'paged'          => $page,
        'posts_per_page' => 6,
    ]);
 
    ob_start();
 
    while ($query->have_posts()) {
        $query->the_post();
        get_template_part('template-parts/card');
    }
 
    wp_reset_postdata();
 
    wp_send_json_success([
        'html'     => ob_get_clean(),
        'has_more' => $page < $query->max_num_pages,
    ]);
}

add_action('wp_ajax_load_more_items', 'wt_load_more_items'); add_action('wp_ajax_nopriv_load_more_items', 'wt_load_more_items'); function wt_load_more_items() { check_ajax_referer('load_more_items', 'nonce'); $page = max(1, (int) ($_POST['page'] ?? 1)); $query = new WP_Query([ 'post_type' => 'post', 'post_status' => 'publish', 'paged' => $page, 'posts_per_page' => 6, ]); ob_start(); while ($query->have_posts()) { $query->the_post(); get_template_part('template-parts/card'); } wp_reset_postdata(); wp_send_json_success([ 'html' => ob_get_clean(), 'has_more' => $page < $query->max_num_pages, ]); }

Передайте данные в JS:

wp_localize_script('theme-main', 'LoadMoreData', [
    'ajaxUrl' => admin_url('admin-ajax.php'),
    'nonce'   => wp_create_nonce('load_more_items'),
]);

wp_localize_script('theme-main', 'LoadMoreData', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('load_more_items'), ]);

JS:

let page = 1;
 
document.querySelector('.js-load-more').addEventListener('click', async function () {
  page++;
 
  const formData = new FormData();
  formData.append('action', 'load_more_items');
  formData.append('nonce', LoadMoreData.nonce);
  formData.append('page', page);
 
  const response = await fetch(LoadMoreData.ajaxUrl, {
    method: 'POST',
    body: formData
  });
 
  const result = await response.json();
 
  if (result.success) {
    document.querySelector('.items-list').insertAdjacentHTML('beforeend', result.data.html);
 
    if (!result.data.has_more) {
      this.remove();
    }
  }
});

let page = 1; document.querySelector('.js-load-more').addEventListener('click', async function () { page++; const formData = new FormData(); formData.append('action', 'load_more_items'); formData.append('nonce', LoadMoreData.nonce); formData.append('page', page); const response = await fetch(LoadMoreData.ajaxUrl, { method: 'POST', body: formData }); const result = await response.json(); if (result.success) { document.querySelector('.items-list').insertAdjacentHTML('beforeend', result.data.html); if (!result.data.has_more) { this.remove(); } } });

Если под “массивом” Вы имеете в виду массив callback-функций, то в PHP можно хранить имена функций и вызывать их через call_user_func(), но для AJAX-загрузки это обычно не нужно. В WordPress нормальная точка входа — action handler.

Не пишите прямой SQL, если можно использовать WP_Query. Так Вы получите корректные статусы, кэш, фильтры, таксономии и совместимость с плагинами.

Если подгружаются видео YouTube или другие внешние элементы, не передавайте в JSON весь произвольный HTML от пользователя без очистки. На сервере формируйте карточку через шаблон, а в JSON отдавайте уже готовый безопасный HTML. Если всё-таки отдаёте массив данных, экранируйте значения при вставке в DOM и не используйте innerHTML для непроверенных строк.

Также добавьте обработку ошибок: блокировку кнопки на время запроса, сообщение при пустом ответе и проверку result.success. Иначе пользователь сможет нажать кнопку несколько раз подряд, получить дубли карточек или не понять, почему загрузка остановилась. Для пагинации храните текущую страницу в JS, а на сервере возвращайте флаг has_more.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно