Как получить конкретную строку ретранслятора ACF с соответствующим значением подполя

Я часами экспериментировал и исследовал, пытаясь найти способ заставить это работать, но мне просто не повезло.

Итак, у меня есть пара разных типов постов, которые нужно немного смешать. Позвольте мне попытаться объяснить это как можно яснее и экономнее.

Есть 2 настраиваемых типа сообщений: сообщения и кампусы. (это большой веб-сайт церкви с несколькими кампусами). Каждое сообщение сообщения будет иметь несколько строк повторителя, основанных на кампусах (через поле таксономии), и каждое сообщение кампуса будет пытаться захватить последнее сообщение сообщения и вытащить конкретную строку повторителя «кампуса» и те же значения полей из этой строки .

Раздел повторителя ACF для отдельного сообщения сообщения ... (мы выбираем одно из сообщений Campus, затем вручную вводим имя докладчика и URL-адрес сообщения)  введите описание изображения здесь

Итак, в настоящий момент я нахожусь в единственном сообщении "Campus", пытаюсь запросить и получить последнее сообщение сообщения, которое работает. Но затем я пытаюсь настроить таргетинг и получить ТОЛЬКО значения определенной строки ретранслятора ВНУТРИ сообщения сообщения. Поля повторителя в сообщении - это поле «Выбор кампуса» (поле выбора на основе поля «Объект публикации» (в типе записи «кампус») и 2 различных текстовых поля.

Чтобы проиллюстрировать ... сообщение сообщения имеет следующие данные ретранслятора: Ряд ретранслятора 1: Выбор кампуса - Трой (сообщение), Спикер сообщения - Дэнни Кокс, URL сообщения - (URL А) Ряд ретранслятора 2: Выбор кампуса - Бирмингем (сообщение ), Диктор сообщения - Клифф Джонсон, URL-адрес сообщения - (URL-адрес B) ... и будет динамическое количество ретрансляторов для нескольких кампусов.

Итак, что я пытаюсь сделать, это следующее ... Внутри моего сообщения Campus - например, "Troy" - я хочу взять последнее сообщение Message, зайти в репитеры и найти строку со значением "Campus Select" . Я хочу вернуть динамик сообщения (Дэнни Кокс) и URL-адрес сообщения (URL-адрес A) ТОЛЬКО из этой строки. Мне ничего не нужно из других рядов.

В моем текущем "последнем сообщении" есть 2 строки повторителя, и вот мой текущий запрос:

<?php
  $args = array(
    'post_type' => 'messages',
    'posts_per_page' => 1
  );

  $latestMessageQuery = new WP_Query($args);
  if( $latestMessageQuery->have_posts() ) { ?>
    <?php while ($latestMessageQuery->have_posts()) : $latestMessageQuery->the_post(); ?>
      <?php if( have_rows('campus_message') ): ?>
        <?php while( have_rows('campus_message') ): the_row(); ?>
          <?php if( get_sub_field('campus_selector') == 'troy' ): ?>
            <?php the_sub_field('message_speaker'); ?>
          <?php else: ?>
            <?php the_sub_field('message_speaker'); ?>
          <?php endif; ?>
        <?php endwhile; ?>
      <?php endif; ?>
    <?php endwhile; ?>
  <?php }
  wp_reset_query();
?>

Для устранения неполадок я вручную пытаюсь получить значение «тройка» «селектор кампуса» вместо того, чтобы получать это значение динамически, исходя из моего текущего местоположения «кампуса» ...

Запрос возвращает оба: «Клифф Джонсон Дэнни Кокс» (так как у меня есть 2 строки повторителя).

Как я могу вернуть ТОЛЬКО: "Трой, Дэнни Кокс, url A" в моем запросе?


person Josh Carey    schedule 07.09.2016    source источник
comment
Учитывая взаимосвязь между данными, я обеспокоен проблемой с настройкой. Как сказано в вашем примере, перед выполнением этого запроса вы получите название поста кампуса, а затем замените . . . == 'troy' этим названием поста. Наконец, удалите соответствующий else, который дает тот же результат. Однако я бы посмотрел на пару альтернатив. 1) рассмотрите другую структуру или 2) используйте собственный запрос к БД (codex.wordpress.org/Class_Reference/wpdb)   -  person Nathan Dawson    schedule 08.09.2016
comment
Привет, Натан, спасибо за ответ ... Согласно выше: Для устранения неполадок ... Я могу динамически получить имя сообщения и вставить его в бит ... == 'troy'. Я могу решить эту часть. Я не думаю, что смогу изменить структуру, так как это уже довольно большой сайт, и наличие единственного сообщения Message, которое предоставляет ретранслятор ACF для каждого отдельного кампуса, кажется гораздо более логичным решением ... скорее чем иметь 7 разных сообщений для каждого кампуса.   -  person Josh Carey    schedule 08.09.2016
comment
Согласно вашему другому предложению, пользовательский запрос к БД выглядит очень сложным для моего уровня квалификации. Можете ли вы привести пример того, как это сработает в моей ситуации?   -  person Josh Carey    schedule 08.09.2016


Ответы (3)


Я предлагаю более прямое решение SQL, используя $wpdb global. Обычно я настоятельно не рекомендую использовать SQL «напрямую», но в этом случае структура метаданных WP и мета-хранилища ACF должна быть стабильной в будущем, потому что поток ACF должен хранить поля как «обычные» мета / настраиваемые поля.

Я публикую это, потому что это довольно простой и лишенный избыточности способ получить определенную строку репитера ACF, найденную по значению подполя.
... полезно, когда у вас МНОГО репитера ACF ряды.

Я собираюсь показать вам пример повторителя в группе полей параметров, потому что я думаю, что это наиболее актуально.

Предположим, у вас есть поле параметров с ключом / именем your_option_name и подполе с ключом / именем subfield_name - обратите внимание на \ экранирование в некоторых частях, это потому, что SQL LIKE использует _ как
специальный символ, что означает «любой отдельный символ»

  $query = 
 "SELECT option_name, option_value FROM {$GLOBALS['wpdb']->prefix}options"
." WHERE option_name LIKE ("
        ." SELECT"
        ." CONCAT( 'options\_your\_option\_name\_', CAST( REPLACE(option_name, 'options_your_option_name_', '' ) AS INTEGER ), '%' )"
        ." FROM {$GLOBALS['wpdb']->prefix}options"
        ." WHERE"
        ." (option_name LIKE 'options\_your\_option\_name\_%\_subfield\_name')"
        ." AND"
        ." (option_value = 'some subfield value')"
      ." LIMIT 0,1"
." )"
  ;

  $results = $GLOBALS['wpdb']->get_results( $query, ARRAY_A );

  if( !empty($results) ){
    foreach($results as $result){
      //do something with it :)
      echo $result['option_name'] . " => " . $result['option_value'];
      echo "<br>";
    }

  }

Основным недостатком этого решения является то, что если у вас есть отформатированные поля, вам нужно позаботиться о форматировании вручную, для поля wysiwyg это довольно просто, просто используйте _ 8_ фильтруют как
echo apply_filters('the_content', $wysiwyg_stored_content);.

Примечание SQL: он в основном ищет prefix_main_key_NUMBER_subkey, затем удаляет prefix_main_key_ из найденного ключа, поэтому остается только NUMBER_subkey => теперь, если вы CAST строка в INTEGER в MySQL / MariaDB и она НАЧИНАЕТ с INTEGER, вы получите INTEGER сюда ... :)

person jave.web    schedule 01.02.2018

Я получил некоторую помощь от службы поддержки ACF по этой проблеме, и следующий код, который они прислали мне, получил то, о чем я просил.

<?php
$args = array(
    'post_type' => 'messages',
    'posts_per_page' => 1
);
$current_campus_id = get_the_ID();

$latestMessageQuery = new WP_Query($args);
if( $latestMessageQuery->have_posts() ) {
    while ($latestMessageQuery->have_posts()) : $latestMessageQuery->the_post();
        if( have_rows('campus_message') ):
            while( have_rows('campus_message') ): the_row();
                if( get_sub_field('campus_selector') == $current_campus_id ):
                    the_sub_field('message_speaker');
                    the_sub_field('message_url');
                    break;
                endif;
            endwhile;
        endif;
    endwhile;
}
wp_reset_query();
?>
person Josh Carey    schedule 10.09.2016
comment
Хотя это работает, кажется ненужным извлекать все строки и выполнять поиск по ним ... - person jave.web; 30.01.2018
comment
Я полностью согласен с тобой. Моя команда в конечном итоге проиграла этот проект (какая-то тупая политика между компаниями), однако мне любопытно узнать, есть ли у вас другое рабочее решение вместо этого ...? - person Josh Carey; 31.01.2018
comment
один из способов - напрямую перейти к SQL, что я обычно не рекомендую делать ... но это должно быть стабильно в будущем :) см. мой ответ - person jave.web; 02.02.2018

Это не будет перебирать все строки, а только читать строку, если ваше подполе соответствует вашему поиску. Надеюсь это поможет

 while (have_rows('repeater_name')) {
      the_row();
      if (get_sub_field('sub_field') != $unique_key) {
        // not our row
        continue;
      }
      // will get here if this is our row
    $sub_field1= get_sub_field('sub_field1');
    $sub_field2= get_sub_field('sub_field2');
    }
person Sneha Agarwal    schedule 16.05.2019