it-swarm.com.ru

Сортировка запроса по данным настраиваемого поля

Правка: переформулировал вопрос для большей ясности

Я пытаюсь отсортировать данные по пользовательским метабоксам, которые я конвертирую в дату, используя функцию strtotime, но у меня возникли некоторые трудности.

Моя главная проблема, кажется, ловушка-22 с функцией strtotime. Если я использую strtotime внутри цикла (см. Ниже), я не могу использовать время UNIX для сортировки по дате. Однако, если я обрабатываю strtotime при сохранении (в functions.php), я сталкиваюсь с множеством проблем, связанных с обновлением/отсутствием синтаксического анализа метабокса, если пользователь редактирует сообщение или повторно сохраняет его.

Есть ли простое решение для этого? Вот код ... Я просто хочу упорядочить эти посты в порядке возрастания по настраиваемому полю даты (а не по дате публикации).

Правка: Исправлен массив путем добавления мета-ключа - решение еще не принято

<!-- The args -->
<?php
$args = array(
    "post_type" => "podcasts",
    "meta-key" => "_date",
    "orderby" => "meta_value",
    "order" => "ASC"
    );
?>

<!-- The Query -->
<?php $podcasts = new WP_Query( $args ); ?>

<!-- The Loop -->
<?php if ( $podcasts->have_posts() ) : while ( $podcasts->have_posts() ) : $podcasts->the_post(); ?>

<!-- Convert Date to Date Stamp -->
<?php $podcast_date = get_post_meta($post->ID, '_date', true);?>
<?php $fixed_date = strtotime($podcast_date); ?>

<!-- Content -->

Правка: Добавлен соответствующий код мета-бокса (ниже) из functions.php Note - Этот код нигде не включает функцию strtotime, потому что в настоящее время я использую ее в шаблоне страницы. Я мог бы включить это здесь, но я не уверен, что сделать, чтобы позволить пользователю редактировать сообщения/сохранять. Когда функция strtotime запускается при сохранении, не изменит ли она дату мета-блока на что-то вроде 1327248252? Если это так, то при следующем сохранении поста это не будет проанализировано, что приведет к возникновению проблем.

// Create podcast Meta boxes

function add_podcast_metaboxes() {
add_meta_box('podcast_info', 'podcast Information', 'podcast_info', 'podcasts',  'normal', 'high');
}

// podcast Meta Box

function podcast_info() {
global $post;

// Noncename needed to verify where the data originated
echo '<input id="podcastmeta_noncename" name="podcastmeta_noncename" type="hidden" value="' .     wp_create_nonce( plugin_basename(__FILE__) ) . '" />';

// Get the data if its already been entered
$week = get_post_meta($post->ID, '_week', true);
$date = get_post_meta($post->ID, '_date', true);
$description = get_post_meta($post->ID, '_description', true);

// Echo out the field
echo '<strong>Week</strong><br /><em>What week of the series is this podcast?</em>';
echo '<input class="widefat" name="_week" type="text" value="' . $week  . '" />';
echo '<strong>Date</strong><br /><em>Enter the Date the podcast was recorded</em>';
echo '<input class="widefat" name="_date" type="text" value="' . $date  . '" />';
echo '<strong>Description</strong><br /><em>Enter the text you would like to display as a description on the media archives list.</em>';
echo '<input class="widefat" name="_description" type="text" value="' . $description  . '" />';

}

// Save the podcast Meta box Data

function save_podcast_meta($post_id, $post) {

// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['podcastmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}

// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ))
    return $post->ID;

// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though.
$podcast_meta['_week'] = $_POST['_week']; 
$podcast_meta['_date'] = $_POST['_date'];
$podcast_meta['_thumbnail'] = $_POST['_thumbnail'];
$podcast_meta['_seriesimg'] = $_POST['_seriesimg'];
$podcast_meta['_description'] = $_POST['_description'];

// Add values of $podcast_meta as custom fields

foreach ($podcast_meta as $key => $value) { // Cycle through the $podcast_meta array!
    if( $post->post_type == 'revision' ) return; // Don't store custom data twice
    $value = implode(',', (array)$value); // If $value is an array, make it a CSV    (unlikely)
    if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
        update_post_meta($post->ID, $key, $value);
    } else { // If the custom field doesn't have a value
        add_post_meta($post->ID, $key, $value);
    }
    if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
}

}
add_action('save_post', 'save_podcast_meta', 1, 2); // save the custom fields
4
timshutes

РЕДАКТИРОВАТЬ: Ваша проблема заключается в следующем:

Когда вы сохраняете свои метаданные, вы хотите, чтобы дата сохранялась как дата strtotime(), но вы хотите, чтобы она отображала дату в старом формате Y-m-d. Что вам нужно сделать, это сохранить его как strtotime(), а затем при отображении текста обратно на входе, вам нужно отменить эту strtotime(), чтобы он мог отображаться правильно. Вы можете сделать это так:

В вашей функции add_podcasts_metaboxes() измените строку, получающую дату, на эту (при условии, что дата всегда будет меткой времени UNIX, если она установлена):

$date = get_post_meta( $post->ID, '_date', true );
if( $date != '' )
    $date = date( 'Y-m-d', $date );

И при сохранении мета в save_podcast_meta(), делайте это как хотите с strtotime():

$podcast_meta['_date'] = strtotime( $_POST['_date'] );

Это превратит дату в метку времени UNIX в базе данных, но с помощью функции date() вы можете превратить эту метку времени UNIX обратно в дату, которую вы можете использовать.


Вам нужно указать мета-ключ, а затем упорядочить meta_value следующим образом:

<!-- The args -->
<?php
$args = array(
    "post_type" => "podcasts",
    "meta_key" => "some_meta_key", // Change to the meta key you want to sort by
    "orderby" => "meta_value_num", // This stays as 'meta_value' or 'meta_value_num' (str sorting or numeric sorting)
    "order" => "ASC"
    );
?>

<!-- The Query -->
<?php $podcasts = new WP_Query( $args ); ?>

<!-- The Loop -->
<?php if ( $podcasts->have_posts() ) : while ( $podcasts->have_posts() ) : $podcasts->the_post(); ?>

<!-- Convert Date to Date Stamp -->
<?php $podcast_date = get_post_meta($post->ID, '_date', true);?>
<?php $fixed_date = strtotime($podcast_date); ?>

<!-- Content -->

См. Эту страницу кодекса для справки: http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

РЕДАКТИРОВАТЬ: Я вижу одну (возможную) проблему с кодом мета-бокса, которую вы только что добавили. Не уверен на 100%!

Попробуйте заменить:

echo '<input id="podcastmeta_noncename" name="podcastmeta_noncename" type="hidden" value="' .     wp_create_nonce( plugin_basename(__FILE__) ) . '" />';

с:

wp_nonce_field( plugin_basename( __FILE__ ), 'podcastmeta_noncename' );

Я не уверен, решит ли это вашу проблему или что-то изменит, но именно так я использую nonce в своих метабоксах (хотя я верю, что есть другой способ сделать это, чтобы избавиться от этой Notice, если вы для WP_DEBUG установлено значение true).

6
Jared

Вы столкнулись с аналогичной проблемой, с которой я столкнулся, и я пытался работать с предлагаемыми решениями/манипулировать ими безрезультатно.

В итоге я использовал http://tablesorter.com/docs и запросил данные мета-бокса прямо в столбцы таблицы. Это работает отлично, а также автоматически сортирует даты соответствующим образом.

Надеюсь это поможет...

1
Dan

Ответы выше отличные. Еще одна полезная тактика, о которой следует помнить, заключается в том, что если у вас уже есть массив данных, вы можете отсортировать данные на стороне сервера (по сравнению с базой данных) используя PHP usort, uasort и uksort .

Чтобы сделать это, вы передаете массив в качестве первого аргумента, а в качестве его второго присваивает методу имя функции, которая впоследствии будет использоваться в качестве обратного вызова. Вам просто нужно, чтобы эта функция возвращала 1, 0 или -1 для сортировки по любому пользовательскому рецепту.

1
editor

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

Я ищу что-то вроде этого:

http://www.designhammer.com/blog/sorting-events-date-using-wordpress-custom-post-types

Тем не менее, я не совсем на уровне php, где я могу взять то, что он делает, и применить это к моей ситуации. Похоже, он добавляет некоторую логику в functions.php, где функция strtotime будет срабатывать, только если время в хорошем формате. Это решило бы мою проблему и позволило бы мне разобраться в интерфейсе.

Мысли?

0
timshutes