Сравните meta_value в WP_Query, который хранится в виде сериализованного массива - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть мета-поле, связанное с пользовательским типом записи.Мета-блок позволяет пользователю выбрать несколько вариантов из раскрывающегося списка, а затем сохраняет его в виде сериализованного массива в базу данных.Если пользователь выбирает только одну опцию, значение meta_value сохраняется как целое число, но если пользователь выбирает несколько опций, оно сохраняется в виде сериализованного массива.

Ниже приведены функции, которые отображают и сохраняют мое мета-поле.

<code>function av_add_meta_box() {

  $post_types = array( 'advertisements' );

  foreach ( $post_types as $post_type ) {

    add_meta_box(
      'avd_screen_meta_box',         // Unique ID of meta box
      'Set Screen',     // Title of meta box
      'av_display_meta_box', // Callback function
      $post_type                   // Post type
    );

  }

}
add_action( 'add_meta_boxes', 'av_add_meta_box' );

// display meta box
function av_display_meta_box( $post ) {

  $value = get_post_meta( $post->ID, '_av_meta_key', true );

  if ( isset( $values['av-meta-box'] ) ) {
        $value = esc_attr( $values['ued-av-box'][0] );
    }

  wp_nonce_field( basename( __FILE__ ), 'av_meta_box_nonce' );

  //echo "<pre>"; print_r($value) ; echo "
";?>Выберите экран место нахождения));$ selected = "";if (gettype ($ value) == "array") {$ selected = (in_array ($ screen-> id, $ value))? "selected": "";} else {$ selected = ($ screen-> id == $ value)? "selected": "";}?>значение =»Я бы;?> ">screen_name. "-". $ location_name [0] -> location_name. "(". $ location_name [0] -> pin. ")";?>

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Я бы предложил сохранить (несколько) значений в несколько строк в базе данных, чтобы избежать проблемы с самого начала. WordPress поддерживает сохранение нескольких значений одним ключом для настраиваемого поля.

Вы можете переписать код, который сохраняет значение в:

if ( array_key_exists( 'av-meta-box', $_POST ) ) {
    delete_post_meta( $post_id, '_av_meta_key' );

    $values = array_map( 'absint', $_POST[ 'av-meta-box' ] );

    foreach ( $values as $value ) {
          add_post_meta( $post_id, '_av_meta_key', $value, false );
    }
}

Таким образом, вы можете написать свой запрос, не беспокоясь о сериализации данных. А получить значения из базы данных просто, как:

$values = get_post_meta( $post_id, '_av_meta_key', false );

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

0 голосов
/ 16 сентября 2018

Трудно получить правильный результат, используя WP_Query с сериализованными данными.Вы можете попробовать использовать ключевое слово LIKE вместо IN.

В качестве альтернативы вы можете использовать пользовательский запрос $wpdb, чтобы получить то, что вы ищете.

global $wpdb;

$posts = $wpdb->get_results(
  $wpdb->prepare(
    "
    SELECT *
    FROM $wpdb->postmeta
    LEFT JOIN $wpdb->posts as post
    ON post.id = post_id
    WHERE post.post_type = %s
    AND meta_key = %s
    AND meta_value LIKE %s
    ",
    'advertisements',
    '_av_meta_key',
    ':"6";'
  )
);

// Check if anything was found
if( $posts !== NULL ) {
  foreach($posts as $post_info) {
    // $post_info contains all post info as object
    echo $post_info->post_title;
  }
}

Вы можетеизмените часть, где это :"6"; на значение, которое вы ищете.Поиск будет лучше, если вы заключите число в :"{number}";", так как в вашем примере оно будет сериализовано, что сделает его более точным совпадением

Обновление: установка мета-ключа для каждого идентификатора экрана

<code>function av_add_meta_box() {

  $post_types = array( 'advertisements' );

  foreach ( $post_types as $post_type ) {

    add_meta_box(
      'avd_screen_meta_box',         // Unique ID of meta box
      'Set Screen',     // Title of meta box
      'av_display_meta_box', // Callback function
      $post_type                   // Post type
    );

  }

}
add_action( 'add_meta_boxes', 'av_add_meta_box' );

// display meta box
function av_display_meta_box( $post ) {

  $value = get_post_meta( $post->ID, '_av_meta_key', true );

  if ( isset( $values['av-meta-box'] ) ) {
        $value = esc_attr( $values['ued-av-box'][0] );
    }

  wp_nonce_field( basename( __FILE__ ), 'av_meta_box_nonce' );

  //echo "<pre>"; print_r($value) ; echo "
";?>Выберите экран место нахождения));$ selected = "";if (gettype ($ value) == "array") {$ selected = (in_array ($ screen-> id, $ value))? "selected": "";} else {$ selected = ($ screen-> id == $ value)? "selected": "";}?>значение =»Я бы;?> ">screen_name. "-". $ location_name [0] -> location_name. "(". $ location_name [0] -> pin. ")";?> id, in_array ($ screen-> id, $ selected_screens)?'да нет' );}}} add_action ('save_post', 'av_save_meta_box');

Затем, когда вы захотите использовать WP_Query, вы можете построить массив для поиска всех ключей и установить отношение OR.

$meta_query = [
  'relation' => 'OR',
];

$screens    = json_decode(apply_filters("av_load_screens", "all"));

foreach($screens as $screen) {
  $meta_query[] = [
    'key'       => '_av_meta_key_' . $screen->id,
    'value'     => 'yes',
    'compare'   => '='
  ];
}

$args = array(
  'post_type'  => 'advertisements',
  'meta_query' => $meta_query,
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...