web-dev-qa-db-fra.com

Tri d'une requête par date de champ personnalisé

EDIT: Reformulé la question pour plus de clarté

J'essaie de trier les données de métadonnées personnalisées, que je convertis en date à l'aide de la fonction strtotime, mais j'ai quelques difficultés.

Mon principal problème semble être un catch-22 avec la fonction strtotime. Si j'utilise strtotime dans la boucle (voir ci-dessous), je ne peux pas utiliser l'heure UNIX pour trier par date. Cependant, si je traite le strtotime lors de la sauvegarde (dans functions.php), je rencontre de nombreux problèmes avec la mise à jour/la non analyse de la boîte méta si l’utilisateur modifie la publication ou la réenregistre.

Y a-t-il une solution simple à cela? Voici le code ... Je veux juste commander ces publications dans l'ordre croissant par le champ de date personnalisé (pas la date affichée).

EDIT: Correction du tableau en ajoutant une méta-clé - solution toujours en attente

<!-- 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 -->

EDIT: Ajout du code de méta-boîte pertinent (ci-dessous) à partir de functions.php Remarque - Ce code n'inclut la fonction strtotime nulle part, car je l'utilise actuellement sur le modèle de page. Je pourrais l'inclure ici, mais je ne suis pas sûr de ce qu'il faut faire pour permettre à l'utilisateur de modifier les messages/de les enregistrer à nouveau. Une fois que la fonction strtotime est exécutée lors de la sauvegarde, ne changez-vous pas la date de la méta-boîte en 1327248252? Si tel est le cas, il ne sera pas analysé à la prochaine sauvegarde de la publication, ce qui créera des problèmes.

// 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

EDIT: Votre problème est le suivant:

Lorsque vous enregistrez vos métadonnées, vous souhaitez que la date soit enregistrée en tant que date strtotime(), mais que vous souhaitez afficher la date dans l'ancien format Y-m-d. Ce que vous devez faire, c'est l'enregistrer sous strtotime(). Ensuite, lorsque vous affichez le texte dans l'entrée, vous devez inverser cette strtotime() afin qu'il puisse être affiché correctement. Vous pouvez le faire comme suit:

Dans votre fonction add_podcasts_metaboxes(), modifiez la ligne qui obtient la date en ceci (en supposant que la date sera toujours un horodatage UNIX s'il n'y a qu'un seul ensemble):

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

Et lorsque vous enregistrez la méta dans save_podcast_meta(), faites-le comme vous le souhaitez avec strtotime():

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

Cela transformerait la date en horodatage UNIX dans la base de données, mais avec la fonction date(), vous pouvez reconvertir cet horodatage UNIX en une date utilisable.


Vous devez spécifier une clé méta, puis orderby meta_value comme suit:

<!-- 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 -->

Voir cette page du codex pour référence: http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

EDIT: Je vois un problème (possible) avec le code de votre boîte méta que vous venez d’ajouter. Pas sûr à 100% cependant!

Essayez de remplacer:

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

avec:

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

Je ne sais pas si cela résoudra votre problème ou fera une grande différence, mais c’est ainsi que j’utilise nonce dans mes boîtes de méta (bien que je croie qu’il existe un autre moyen de le faire pour éviter de le supprimer. Notice si WP_DEBUG défini sur true).

6
Jared

Vous faites face à un problème similaire que j'ai et j'essayais de travailler/manipuler les solutions proposées sans résultats.

J'ai fini par utiliser http://tablesorter.com/docs et interroger mes données de méta-boîte directement dans les colonnes de la table. Cela a parfaitement fonctionné et trie automatiquement les dates de manière appropriée.

J'espère que cela t'aides...

1
Dan

Les réponses ci-dessus sont excellentes. Une autre tactique utile à garder à l'esprit est que si vous avez déjà un tableau de données, vous pouvez trier côté serveur (vs côté base de données) en utilisant les variables usort, uasort et uksort .

Pour ce faire, vous passez le tableau en tant que premier argument et, en second lieu, donnez à la méthode le nom d'une fonction qui sera utilisée ultérieurement comme rappel. Vous avez juste besoin que cette fonction retourne 1, 0 ou -1 pour trier par n'importe quelle recette personnalisée.

1
editor

Je me rends compte que je devrais mettre ceci dans mon message original - mais cela devient très encombré, et cela se prête à une réponse.

Je cherche quelque chose comme ça:

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

Cependant, je ne suis pas tout à fait au niveau php où je peux prendre ce qu'il fait et l'appliquer à ma situation. Il semble qu’il ajoute une certaine logique dans functions.php où la fonction strtotime ne sera déclenchée que si l’heure est au bon format. Cela résoudrait mon problème et me permettrait de trier sur le front-end.

Pensées?

0
timshutes