Existe-t-il un moyen de filtrer tous les champs personnalisés d'une publication?
Supposons pour une simplicité très élémentaire que j'ai:
champs standard de:
les champs personnalisés:
Supposons au chargement de la page que je veux ajouter 123456 à la fin de chaque valeur de champs personnalisés, mais que je souhaite le faire avec un filtre. Quel add_filter pourrait accomplir cela? Un petit texte de code serait utile.
Modifiez selon la réponse actuelle:
Après avoir travaillé sur la première réponse, je me suis heurté à un problème qui ne fonctionnerait que sur le premier champ. J'ai alors réalisé que je devais passer en revue chaque élément et c'est ce que j'ai. Ce qui est étrange, c’est que les données semblent intactes, mais la page n’affiche pas les nouvelles données. J'ai des commentaires dans mon code ci-dessous:
function my_post_meta_filters($null, $post_id, $key, $single){
if(is_admin() || (substr($key, 0, 8) != '_author_' && substr($key, 0, 7) != '_quote_')){
return $null;
}
static $filtered_values = NULL;
if(is_null($filtered_values)){
$cache = update_postmeta_cache(array($post_id));
$values = $cache[$post_id];
//must loop through all the fields or else only the first field is affected
foreach($values AS $valkey => $value){
if(substr($key, 0, 8) == '_author_' || substr($key, 0, 7) == '_quote_'){
$filtered[$valkey] = filtered($values[$valkey][0]);
$filtered[$valkey] = maybe_serialize($filtered[$valkey]); //at this point the data is correct and even reserialized where expected
$filtered_values[$valkey] = $filtered[$valkey];
}
}
return $filtered_values;
}
}
add_filter('get_post_metadata', 'my_post_meta_filters', 0, 4);
function filtered($it){
if(!is_array($it) && !is_serialized($it)){
$filtered = apply_filters('number_filter', $it); //adds numbers to the end
} else {
//otherwise we ran into a serialized array so lets unserialize and run each part through our function
$unserialized = maybe_unserialize($it);
$filtered = array_map('filtered', $unserialized);
}
return $filtered;
}
En interne, les méta sont gérés via un cache d’objets difficilement filtrable.
La seule possibilité de filtrer les métadonnées de publication consiste à utiliser le 'get_post_metadata'
, mais ce filtre est déclenché lorsque les métadonnées ne sont pas disponibles. Il n'y a donc rien à filtrer. il était destiné à court-circuiter le résultat plus qu'à le filtrer.
La solution que je propose est donc:
Alors, commencez par ajouter le filtre:
add_filter( 'get_post_metadata', 'my_post_meta_filters', 0, 4 );
Puis écrivez le rappel de hooking
function my_post_meta_filters( $null, $pid, $key, $single ) {
if ( ! in_array( $key, array( 'author', 'ISBN', 'quote', '' ), TRUE ) || is_admin() ) {
return $null;
};
static $filtered_values = NULL;
if ( is_null( $filtered_values ) ) {
$cache = update_meta_cache( 'post', array( $pid ) );
$values = $cache[$pid];
$raw = array(
'author' => isset( $values['author'] ) ? $values['author'] : NULL,
'ISBN' => isset( $values['ISBN'] ) ? $values['ISBN'] : NULL,
'quote' => isset( $values['quote'] ) ? $values['quote'] : NULL,
);
// this is the filter you'll use to filter your values
$filtered = (array) apply_filters( 'my_post_meta_values', $raw, $pid );
foreach ( array( 'author', 'ISBN', 'quote' ) as $k ) {
if ( isset( $filtered[$k] ) ) $values[$k] = $filtered[$k];
}
$filtered_values = $values;
}
if ( $key === '' )
$filtered_values;
if ( ! isset( $filtered_values[$key] ) )
return;
return $single
? maybe_unserialize( $filtered_values[$key][0] )
: array_map( 'maybe_unserialize', $filtered_values[$key] );
}
En ayant cette fonction dans votre code, vous pourrez filtrer vos champs personnalisés à l'aide du filtre personnalisé 'my_post_meta_values'
.
Juste un exemple:
add_filter( 'my_post_meta_values', function( $values, $post_id ) {
// append '123456' to all values
if ( is_array( $values['author'] ) ) {
$values['author'][0] .= ' 123456';
}
if ( is_array( $values['ISBN'] ) ) {
$values['ISBN'][0] .= ' 123456';
}
if ( is_array( $values['quote'] ) ) {
$values['quote'][0] .= ' 123456';
}
return $values;
}, 10, 2 );
Avec ce filtre actif, si vous le faites:
echo get_post_meta( $post_id, 'author', TRUE );
et votre champ personnalisé "auteur" est défini sur "Shawn" alors que le résultat est "Shawn 123456".
Notez que my_post_meta_filters
est également compatible avec get_post_custom
sans effort supplémentaire.