J'utilise cette fonction depuis ceci accepté réponse, qui obtient toutes les valeurs pour une clé de champ personnalisée (cross-post).
Comment pourrait-il être modifié pour permettre un tableau des statuts de publication?
function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {
global $wpdb;
if( empty( $key ) )
return;
$r = $wpdb->get_col( $wpdb->prepare( "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status = '%s'
AND p.post_type = '%s'
", $key, $status, $type ) );
return $r;
}
par exemple quelque chose comme ça (ça ne marche pas)
function get_meta_values( $key = '', $type = 'post', $status = array( 'publish', 'draft' ) ) {
global $wpdb;
if( empty( $key ) )
return;
$r = $wpdb->get_col( $wpdb->prepare( "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status = '%s'
AND p.post_type = '%s'
", $key, $status, $type ) );
return $r;
}
Il suffit d'imploser le tableau passé:
function get_meta_values( $key = '', $type = 'post', $status = array( 'publish', 'draft' ) ) {
global $wpdb;
if( empty( $key ) )
return;
//First escape the status, since we don't use it with $wpdb->prepare()
$status = esc_sql( $status );
//If its an array, convert to string
if( is_array( $status ) ){
$status = implode( ', ', $status ); //e.g. "publish, draft"
}
$r = $wpdb->get_col( $wpdb->prepare(
"SELECT pm.meta_value FROM {$wpdb->postmeta} AS pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = %s
AND p.post_status IN( {$status} )
AND p.post_type = %s",
$key, $type ) );
return $r;
}
Cela vous permet de passer $status
sous forme de chaîne ou de tableau.
Utilisez l’opérateur IN pour les tableaux.
Lorsque vous utilisez $wpdb->prepare()
, vous n'êtes pas obligé d'utiliser des guillemets autour de l'espace réservé à la chaîne %s
. L'espace réservé à la chaîne sera cité automatiquement. C'est aussi la raison pour laquelle vous devez prendre des précautions lors de l'utilisation de $wpdb->prepare()
avec l'opérateur IN si les valeurs du tableau sont des chaînes.
Ce premier exemple n'utilise pas les espaces réservés pour post stati mais les insère directement (séparés par des virgules et citées) dans la chaîne de requête
function get_meta_values( $key = '', $type = 'post', $status = array( 'publish', 'draft' ) ) {
global $wpdb;
if ( empty( $key ) ) {
return;
}
// escape the status values
$status = array_map( 'esc_sql', (array) $status );
// $status_string: a comma separated string with quoted post stati
// $status_string = "'publish', 'draft'";
$status_string = "'" . implode( "', '", $status ) . "'";
$query = "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status IN ( $status_string )
AND p.post_type = '%s'";
$r = $wpdb->get_col( $wpdb->prepare( $query, $key, $type ) );
return $r;
}
Ce deuxième exemple convertit le tableau avec la méthode de cette réponse https://stackoverflow.com/a/10634225
function get_meta_values( $key = '', $type = 'post', $status = array( 'publish', 'draft' ) ) {
global $wpdb;
if ( empty( $key ) ) {
return;
}
// $status_string: a comma separated string with string placeholders (%s)
// $status_string = "%s, %s";
$status_string = implode( ', ', array_fill( 0, count( $status ), '%s' ) );
//parameters array for call_user_func_array callback function $wpdb->prepare
$prepare = array();
// the query is the first parameter
$prepare[] = "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = %s
AND p.post_status IN ($status_string)
AND p.post_type = %s
";
// from here on out add to the $prepare array in the same order as inside the query
$prepare[] = $key;
foreach ( $status as $s ) {
$prepare[] = $s;
}
$prepare[] = $type;
// calling $wpdb->prepare() with the $prepare array
$query = call_user_func_array( array( $wpdb, 'prepare' ), $prepare );
$r = $wpdb->get_col( $query );
return $r;
}
Remarque: les deux exemples doivent être codés de manière plus défensive (is_array (), etc.) s'ils sont utilisés en production.