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


ИЗМЕНИТЬ: Переформулировал вопрос для большей ясности

Я пытаюсь отсортировать по пользовательским данным метаданных, которые я преобразую в дату с помощью функции 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 Примечание - Этот код нигде не включает функцию 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
Author: timshutes, 2012-01-21

4 answers

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

Когда вы сохраняете свои метаданные, вы хотите, чтобы дата была сохранена как дата 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
Author: Jared, 2012-01-24 18:08:58

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

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

 1
Author: editor, 2012-01-23 19:20:14

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

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

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

 1
Author: Dan, 2012-06-27 17:48:21

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

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

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

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

Мысли?

 0
Author: timshutes, 2012-01-24 15:22:51